# require sequel here to ensure other mods are underneath it
require_relative "./gxg_sqlite.rb"
require_relative "./gxg_mysql.rb"
require_relative "./gxg_postgres.rb"
require "sequel"
require "securerandom"
require "openssl"
require "base64"
require "net/ldap"

module GxG
  DB_SAFETY = ::Mutex.new
  DB = {:cache => {}, :formats => {}, :authority => nil, :administrator => nil, :roles => {}}
  #
  module Database
    # Class Place-holder Definitions
    class DetachedArray
      #
    end
    class DetachedHash
      #
    end
    class PersistedArray
      #
    end
    class PersistedHash
      #
    end
    #
    def self.element_tables()
      {
      :unspecified => nil,
      :element_boolean => [::TrueClass, ::FalseClass, ::NilClass],
      :element_integer => [::Integer],
      :element_float => [::Float],
      :element_bigdecimal => [::BigDecimal],
      :element_datetime => [::DateTime],
      :element_text => [::String],
      :element_binary => [::GxG::ByteArray],
      :element_array => [::Array],
      :element_hash => [::Hash]
      }
    end
    #
    def self.valid_field_classes()
      [::TrueClass, ::FalseClass, ::NilClass, ::Integer, ::Float, ::BigDecimal, ::DateTime, ::String, ::GxG::ByteArray]
    end
    def self.element_table_index(the_key=:unspecified)
      (::GxG::Database::element_tables().keys.index(the_key.to_sym) || 0)
    end
    #
    def self.element_table_by_index(the_index=0)
      (::GxG::Database::element_tables().keys[(the_index)] || :unspecified)
    end
    #
    def self.element_table_for_instance(the_instance=nil)
      result = :unspecified
      #
      table = ::GxG::Database::element_tables()
      table.keys.each do |the_key| 
        unless the_key == :unspecified
          if the_instance.is_any?(table[(the_key)])
            result = the_key
            break
          end
        end
      end
      #
      result
    end
    #
    def self.persistable?(the_object)
      result = true
      unless the_object.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
        if the_object.is_any?(::Hash, ::Array)
          the_object.search do |item, selector, container|
            if result
              if ::GxG::Database::element_table_for_instance(item) == :unspecified
                result = false
                break
              end
            end
            nil
          end
        else
          if ::GxG::Database::element_table_for_instance(the_object) == :unspecified
            result = false
          end
        end
      end
      result
    end
    #
    def self.iterative_detached_persist(old_root=nil)
      # New PersistedArray, or PersistedHash interface:
      # 
      result = nil
      begin
        # db open?
        # write permissions on db?
        unless old_root.is_any?(::Array, ::Hash)
          raise ArgumentError, "You MUST provide either an Array or a Hash."
        end
        unless GxG::Database::persistable?(old_root)
          raise ArgumentError, "The object you are attempting to persist contains a non-persistable item."
        end
        #
        if old_root.is_a?(::Array)
          original_partner = ::GxG::Database::DetachedArray.new()
          #
        end
        if old_root.is_a?(::Hash)
          original_partner = ::GxG::Database::DetachedHash.new()
        end
        #
        paring_data = [{:parent => nil, :parent_selector => nil, :object => old_root, :partner => original_partner}]
        children_of = Proc.new do |the_parent=nil|
          list = []
          paring_data.each do |node|
            if node[:parent].object_id == the_parent.object_id
              list << node
            end
          end
          list
        end
        #
        parent_of = Proc.new do |the_parent=nil|
          output = nil
          paring_data.each do |entry|
            if entry[:object].object_id == the_parent.object_id
              output = entry
            end
          end
          output
        end
        find_partner = Proc.new do |the_object|
          found_partner = nil
          paring_data.each do |the_record|
            if the_record.is_a?(::Hash)
              if the_record[:object].object_id == the_object.object_id
                found_partner = the_record[:partner]
                break
              end
            end
          end
          found_partner
        end
        # build paring data:
        delegate_permission = nil
        old_root.search do |the_value, the_selector, the_container|
          if the_value.is_a?(::Array)
            paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => ::GxG::Database::DetachedArray.new()}
          else
            if the_value.is_a?(::Hash)
              paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => ::GxG::Database::DetachedHash.new()}
            else
              paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => the_value}
            end
          end
        end
        #
        # Assign objects to structure in order by parent / parent_selector
        link_db = [(paring_data[0])]
        while link_db.size > 0
          entry = link_db.shift
          if entry.is_a?(::Hash)
            if entry[:object].is_any?(::Array, ::Hash)
              # get children and assign
              children = children_of.call(entry[:object])
              children.each do |child|
                entry[:partner][(child[:parent_selector])] = child[:partner]
                if child[:partner].is_any?(::GxG::Database::DetachedArray, ::GxG::Database::DetachedHash)
                  link_db << child
                end
              end
            end
          end
        end
        result = original_partner
      rescue Exception => the_error
        log_error({:error => the_error, :parameters => {:object => old_root}})
      end
      result
    end
    #
    def self.detached_format_find(the_criteria={})
      result = nil
      tests = {}
      [:uuid, :ufs, :title, :version].each do |the_key|
        if the_criteria[(the_key)]
          tests[(the_key)] = the_criteria[(the_key)]
        end
      end
      GxG::DB[:formats].each_pair do |uuid,record|
        score = 0
        tests.keys.each do |the_test|
          if record[(the_test)] == tests[(the_test)]
            score += 1
          end
        end
        if tests.keys.size == score
          result = record
          break
        end
      end
      result
    end
    #
    def self.detached_format_load(the_criteria={}, &block)
      # If already loaded and block provided: return an Array of format records.
      # Load any missing formats from server, and call block if provided.
      # Note: results are in NO particular order (DO NOT INDEX into the result set from source criteria)
      success = false
      needed = []
      results = []
      if the_criteria.is_a?(::Hash)
        loaded = ::GxG::Database::detached_format_find(the_criteria)
        if loaded
          results << loaded
          if block.respond_to?(:call)
            block.call(results)
          end
          success = true
        else
          needed << the_criteria
        end
      else
        if the_criteria.is_a?(::Array)
          the_criteria.each do |the_specifier|
            loaded = ::GxG::Database::detached_format_find(the_specifier)
            if loaded
              results << loaded
            else
              needed << the_specifier
            end
          end
        end
      end
      if needed.size > 0
        if ::GxG::DB[:roles][:format].is_a?(::GxG::Database::Database)
          needed.each do |the_specifier|
            format_record = ::GxG::DB[:roles][:format].format_load({:uuid => the_specifier.to_s.to_sym})
            if format_record
              GxG::DB[:formats][(format_record[:uuid].to_sym)] = format_record
              results << format_record
            end
          end
          if block.respond_to?(:call)
            block.call(results)
          end
          success = true
        end
      else
        if results.size > 0
          if block.respond_to?(:call)
            block.call(results)
          end
          success = true
        end
      end
      #
      success
    end
    #
    def self.process_detached_import(import_manifest=nil, options={})
        result = []
        if import_manifest.is_a?(::Hash)
            if import_manifest[:formats].size > 0
                # import formats: GxG::DB[:formats]
                import_manifest[:formats].keys.each do |the_key|
                    unless GxG::DB[:formats][(the_key)]
                      # Review do ::Hash.gxg_import on format content
                      format_record = import_manifest[:formats][(the_key)]
                      if format_record[:version].is_a?(::String)
                        format_record[:version] = BigDecimal.new(format_record[:version])
                      end
                      format_record[:content] = ::Hash.gxg_import(format_record[:content])
                      GxG::DB[:formats][(the_key)] = format_record
                    end
                end
            end
            #
            if import_manifest[:records].size > 1
              import_manifest[:records].each do |the_record|
                result << GxG::Database::DetachedHash::import(the_record)
              end
            else
              result << GxG::Database::DetachedHash::import(import_manifest[:records][0])
            end
        end
        result
    end
    #
    def self.process_import(import_manifest=nil, credential=nil, options={})
      # sync_import(credential=nil, the_records={:formats => {}, :records => []}, options={})
      result = false
      if import_manifest.is_a?(::Hash) && ::GxG::valid_uuid?(credential) && options.is_a?(::Hash)
        options = {:role => :data}.merge!(options)
        database = ::GxG::DB[:roles][(options[:role])]
        if database.is_a?(::GxG::Database::Database)
          if ::GxG::DB[:roles][:format].is_a?(::GxG::Database::Database)
            unless database == ::GxG::DB[:roles][:format]
              ::GxG::DB[:roles][:format].sync_import(credential, {:formats => import_manifest[:formats], :records => []}, options)
            end
          end
          #
          result = database.sync_import(credential, import_manifest, options)
        else
          log_warn("No suitable database of role #{options[:role].inspect} could be found for the import request : Ignoring Request")
        end
      else
        log_warn("Invalid parameters to import request : Ignoring Request")
      end
      result
    end
    #
    def self.as_import_record(records=[], options={})
      result = {:formats => {}, :records => []}
      if records.is_any?(::GxG::Database::DetachedHash, ::GxG::Database::PersistedHash)
        records = [(records)]
      end
      if records.is_any?(::Array, ::GxG::Database::DetachedArray, ::GxG::Database::PersistedArray)
        records.each do |the_object|
          if the_object.is_any?(::GxG::Database::DetachedHash, ::GxG::Database::PersistedHash)
            object_record = the_object.export()
            object_record.search do |item,selector,container|
              if selector == :format || selector == :constraint
                if item.to_s.size > 0
                  format_uuid = item
                  unless result[:formats][(format_uuid.to_s.to_sym)].is_a?(::Hash)
                    if ::GxG::DB[:roles][:format].is_a?(::GxG::Database::Database)
                      format_sample = ::GxG::DB[:roles][:format].format_load({:uuid => format_uuid.to_s.to_sym})
                      format_sample[:content] = format_sample[:content].gxg_export()
                      result[:formats][(format_uuid.to_s.to_sym)] = format_sample
                    end
                  end
                end
              end
            end
            result[:records] << object_record
            #
          end
        end
      end
      result
    end
    #
    def self.connect(the_url, options={})
      # TODO: require :credential (access privs)
      result = nil
      begin
        # check for URI ipv6 [format] compatibility
        db_url = ::URI::parse(the_url.to_s)
        the_path = db_url.path.to_s
        if the_path == ""
          the_path = db_url.hostname.to_s
        end
        if ::RUBY_ENGINE == "jruby"
          # jdbc:sqlite::memory:
          # jdbc:postgresql://localhost/database?user=username
          # jdbc:mysql://localhost/test?user=root&password=root
          # jdbc:h2:mem:
          # jdbc:hsqldb:mem:mymemdb
          # jdbc:derby:memory:myDb;create=true
          # jdbc:sqlserver://localhost;database=sequel_test;integratedSecurity=true
          # jdbc:jtds:sqlserver://localhost/sequel_test;user=sequel_test;password=sequel_test
          # jdbc:oracle:thin:user/password@localhost:1521:database
          # jdbc:db2://localhost:3700/database:user=user;password=password;
          # jdbc:sqlanywhere://localhost?DBN=Test;UID=user;PWD=password
          case db_url.scheme.to_sym
          when :sqlite, :sqlite3
            if ["/memory", "memory"].include?(the_path)
              result = Sequel.connect("jdbc:sqlite::memory:")
            else
              result = Sequel.connect("jdbc:sqlite:" + the_path)
            end
          when :mysql, :mysql2, :mariadb
            result = Sequel.connect(("jdbc:mysql://" + db_url.hostname.to_s + "/" + db_url.path.to_s.split("/").last.to_s + "?user=" + db_url.user.to_s + "&password=" + db_url.password.to_s + "&serverTimezone=UTC"))
          else
            raise Exception, "As-yet unsupported adapter type --> Under Construction"
          end
          #
        else
          case db_url.scheme.to_sym
          when :sqlite, :sqlite3
            if ["/memory", "memory"].include?(the_path)
              result = Sequel.connect("sqlite::memory:")
            else
              result = Sequel.connect("sqlite://" + the_path)
            end
          else
            # auto-forward to mysql2 gem if mysql:// scheme
            if db_url.scheme.to_s == "mysql"
              #
              result = Sequel.connect({:adapter => "mysql2", :host => (db_url.hostname.to_s), :database => (db_url.path.to_s.split("/").last), :user => (db_url.user.to_s), :password => (db_url.password.to_s)})
              #
            else
              #
              result = Sequel.connect({:adapter => (db_url.scheme.to_s), :host => (db_url.hostname.to_s), :database => (db_url.path.to_s.split("/").last), :user => (db_url.user.to_s), :password => (db_url.password.to_s)})
              #
            end
          end
        end
        result = ::GxG::Database::Database.new(result, options.merge({:url => (db_url)}))
      rescue => the_error
        log_error({:error => the_error, :parameters => {:url => (the_url), :options => (options)}})
      end
      result
    end
    # External Authority (Such as LDAP)
    class ExternalAuthority
      def alive?()
        true
      end
    end
    #
    class LDAPAuthority < ::GxG::Database::ExternalAuthority
      #
      def initialize(settings={})
        # Settings: {:host => "localhost", :port => 389, :base_dn => "cn=admin, dc=my-domain, dc=com", :password => "secret-word"}
        @active = false
        @connector = ::Net::LDAP.new
        @connector.host = ::TCPSocket.getaddress(settings[:host].to_s)
        @connector.port = settings[:port].to_s.to_i
        @connector.auth settings[:base_dn].to_s, settings[:password].to_s
        if @connector.bind
          @active = true
        else
          raise "Unable to bind to LDAP host."
        end        
        self
      end
      #
      def open?()
        @active
      end
      #
    end
    # Database class proper
    class Database
      def self.connect(the_url, options={})
        ::GxG::Database::connect(the_url, options)
      end
      #
      def self.element_tables()
        {
          :unspecified => nil,
          :element_boolean => [::TrueClass, ::FalseClass, ::NilClass],
          :element_integer => [::Integer],
          :element_float => [::Float],
          :element_bigdecimal => [::BigDecimal],
          :element_datetime => [::DateTime],
          :element_text => [::String],
          :element_binary => [::GxG::ByteArray],
          :element_array => [::Array],
          :element_hash => [::Hash]
        }
      end
      #
      def self.valid_field_classes()
        [::TrueClass, ::FalseClass, ::NilClass, ::Integer, ::Float, ::BigDecimal, ::DateTime, ::String, ::GxG::ByteArray]
      end
      #
      def self.element_table_index(the_key=:unspecified)
        (::GxG::Database::Database::element_tables().keys.index(the_key.to_sym) || 0)
      end
      #
      def self.element_table_by_index(the_index=0)
        (::GxG::Database::Database::element_tables().keys[(the_index)] || :unspecified)
      end
      #
      def self.element_table_for_instance(the_instance=nil)
        # Review : rewrite - in use
        result = :unspecified
        #
        table = ::GxG::Database::Database::element_tables()
        table.keys.each do |the_key| 
          unless the_key == :unspecified
            if the_instance.is_any?(table[(the_key)])
              result = the_key
              break
            end
          end
        end
        #
        result
      end
      #
      def db_migration()
        # Review : Consider adding support for a ::Symbol class as well. (ease-of-use implications later)
        # Internal mapping of the database format
        # Datatypes - See: http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html
        # Column Options - See: http://sequel.jeremyevans.net/rdoc/classes/Sequel/Database.html#method-i-add_column
        # See also : http://ruby-doc.org/core-2.2.0/Array.html#method-i-pack
        {
          :element_text => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)}
            },
          :text_page => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :parent_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :ordinal => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :content => {:type => :varchar, :options => {:size => 4099, :default => "", :null => false}, :bytes => 4099}
            },
          :element_binary => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :format => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)}
            },
          :binary_page => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :parent_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :ordinal => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :content => {:type => :blob, :options => {:size => 65536}, :bytes => 65536}
            },
          :element_array => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :constraint => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :title => {:type => :varchar, :options => {:size => 259, :null => false, :default => "Untitled"}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
            },
          :array_elements => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :parent_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :ordinal => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :element => {:type => :varchar, :options => {:size => 259, :default => "element_boolean", :null => false}, :bytes => 259},
            :element_boolean => {:type => :integer, :options => {:size => 1, :default => -1}, :bytes => ([ -1 ].pack('l!').length)},
            :element_integer => {:type => :integer, :options => {}, :bytes => ([ -1 ].pack('l!').length)},
            :element_float => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :element_bigdecimal => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :element_datetime => {:type => :datetime, :options => {}, :bytes => 16},
            :time_offset => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :time_prior => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :time_after => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :element_text => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :element_text_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_binary_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_array_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_hash_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40}
          },
          :element_hash => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :format => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :title => {:type => :varchar, :options => {:size => 259, :null => false, :default => "Untitled"}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
            },
          :hash_properties => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :parent_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :property => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :ordinal => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :element => {:type => :varchar, :options => {:size => 259, :default => "element_boolean", :null => false}, :bytes => 259},
            :element_boolean => {:type => :integer, :options => {:size => 1, :default => -1}, :bytes => ([ -1 ].pack('l!').length)},
            :element_integer => {:type => :integer, :options => {}, :bytes => ([ -1 ].pack('l!').length)},
            :element_float => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :element_bigdecimal => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :element_datetime => {:type => :datetime, :options => {}, :bytes => 16},
            :time_offset => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :time_prior => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :time_after => {:type => :float, :options => {:default => 0.0}, :bytes => ([ 0.1 ].pack('d').length)},
            :length => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :element_text => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :element_text_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_binary_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_array_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_hash_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40}
          },
          :element_locks => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :type => {:type => :varchar, :options => {:size => 40,:default => "", :null => false}, :bytes => 40},
            :reservation => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :credential => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :element_table => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :elementid => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)}
          },
          :trash => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :element_table => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :elementid => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)}
          },
          :users => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :user_id => {:type => :varchar, :options => {:size => 259, :null => false, :default => ""}, :bytes => 259},
            :password_hash => {:type => :varchar, :options => {:size => 259, :null => false, :default => ""}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          },
          :roles => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :seo => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :title => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          },
          :user_roles => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :user_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :role_uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          },
          :permissions => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :credential => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :execute => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :rename => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :move => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :destroy => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :create => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :write => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :read => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :element_table => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :elementid => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          },
          :file_permissions => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :file_id => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :credential => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :execute => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :rename => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :move => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :destroy => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :create => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :write => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :read => {:type => :integer, :options => {:default => 0}, :bytes => ([ -1 ].pack('l!').length)},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          },
          :formats => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :type => {:type => :varchar, :options => {:size => 40, :null => false, :default => "structure"}, :bytes => 40},
            :ufs => {:type => :varchar, :options => {:size => 4099, :default => "", :null => false}, :bytes => 4099},
            :title => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256},
            :mime_types => {:type => :varchar, :options => {:size => 4099, :default => "", :null => false}, :bytes => 4099}
          },
          :settings => {
            :dbid => {:type => :integer, :options => {:unique => true, :primary_key => true, :auto_increment => true}, :bytes => ([ -1 ].pack('l!').length)},
            :uuid => {:type => :varchar, :options => {:size => 40, :default => "", :null => false}, :bytes => 40},
            :title => {:type => :varchar, :options => {:size => 259, :default => "", :null => false}, :bytes => 259},
            :version => {:type => :numeric, :options => {:default => ::BigDecimal.new("0.0")}, :bytes => 256}
          }
        }
      end
      #
      def db_format(format_options={})
        # MySql stuff:
        # ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
        # See: https://dev.mysql.com/doc/refman/5.0/en/table-size-limit.html
        result = true
        #
        begin
          if @connector.is_a?(::Sequel::Database)
            case @scheme
            when :sqlite
              @connector.run("PRAGMA page_size=65536")
              @connector.run("PRAGMA max_page_count=281474976710656")
              @connector.run("PRAGMA encoding='UTF-8'")
            when :mysql, :mysql2
              @connector.run("SET GLOBAL max_allowed_packet = 17825792;")
              @connector.run("SET NAMES 'utf8' COLLATE 'utf8_general_ci';")
              @connector.run("SET collation_connection = 'utf8_general_ci';")
            when :postgres
              # place holder
            end
            migration = db_migration()
            migration.keys.each do |the_table|
              unless @connector.table_exists?(the_table)
                  @connector.create_table(the_table) do
                  primary_key :dbid
                end
              end
              used_bytes = 0
              #
              existing_columns = @connector[(the_table)].columns
              migration[(the_table)].keys.each do |the_column|
                used_bytes += (migration[(the_table)][(the_column)][:bytes]).to_i
                if existing_columns.include?(the_column)
                  # TODO: figure out a way to inspect columns for attributes -> detailed verification
                else
                  # collation for mysql
                  if @scheme == :mysql
                    # Note: might have to specify :collate first, use -> {:collate => ""}.merge(migration[(the_table)][(the_column)][:options])
                    if migration[(the_table)][(the_column)][:type] == :varchar
                      # migration[(the_table)][(the_column)][:options] = {:collate => "utf8_general_ci"}.merge(migration[(the_table)][(the_column)][:options])
                      migration[(the_table)][(the_column)][:options][:collate] = "utf8_general_ci"
                    end
                    if migration[(the_table)][(the_column)][:type] == :blob
                      # migration[(the_table)][(the_column)][:options] = {:collate => "binary"}.merge(migration[(the_table)][(the_column)][:options])
                      # Note: MySQL 5 doesn't like putting collation on blobs! (blows up)
                      # migration[(the_table)][(the_column)][:options][:collate] = "binary"
                    end
                  else
                  end
                  # do the deed
                  @connector.add_column((the_table), (the_column), (migration[(the_table)][(the_column)][:type]), (migration[(the_table)][(the_column)][:options]))
                  #
                end
              end
              #
              if @scheme == :mysql
                # @connector.run("ALTER TABLE #{the_table.to_s} MAX_ROWS=18446744073709551616 AVG_ROW_LENGTH=#{used_bytes.to_s};")
              end
              #
            end
          else
            raise Exception, "Invalid db connection"
          end
        rescue Exception => the_error
          result = false
          log_error({:error => the_error, :parameters => format_options})
        end
        #
        result
      end
      #
      def db_formatted?()
        result = true
        #
        begin
          if @connector.is_a?(::Sequel::Database)
            migration = db_migration()
            migration.keys.each do |the_table|
              unless @connector.table_exists?(the_table)
                result = false
                break
              end
              #columns
              existing_columns = @connector[(the_table)].columns
              migration[(the_table)].keys.each do |the_column|
                unless existing_columns.include?(the_column)
                  result = false
                  break
                end
              end
              #
              unless (result)
                break
              end
            end
          else
            raise Exception, "Invalid db connection"
          end
        rescue Exception => the_error
          result = false
          log_error({:error => the_error, :parameters => nil})
        end
        #
        result
      end
      #
      def open?()
        begin
          @connector.synchronize do |connection|
            @active = @connector.valid_connection?(connection)
          end
        rescue => the_error
          @active = false
          log_error({:error => the_error, :parameters => nil})
        end
        @active
      end
      #
      def close()
        # place holder for now.
        if @authority
          @authority.db_unregister(self)
        end
      end
      #
      def connector()
        @connector
      end
      #
      #
      def to_uri()
        ::URI.parse(@url.to_s)
      end
      #
      def inspect()
        "<Database: #{self.to_uri()}>"
      end
      # ### Permission Handling methods
      def db_permissions
        @base_permissions.clone
      end
      # ### Authority support
      def db_register(the_db)
        if the_db.is_a?(::GxG::Database::Database)
          unless @db_list.find_index(the_db)
            @db_list << the_db
          end
        end
      end
      #
      def db_unregister(the_db)
        if the_db.is_a?(::GxG::Database::Database)
          if @db_list.find_index(the_db)
            @db_list.delete_at(@db_list.find_index(the_db))
          end
        end
      end
      #
      def db_list()
        result = []
        @db_list.each do |the_db|
          result << the_db
        end
        result
      end
      # ### User, Role, and Group methods
      #
      def user_manifest(include_password=false)
        result = []
        if @authority
          result = @authority.user_manifest(include_password)
        else
          if self.alive?
            if self.open?
              begin
                if include_password == true
                  dataset = @connector[:users].select(:uuid, :user_id, :password_hash, :version).all
                else
                  dataset = @connector[:users].select(:uuid, :user_id, :version).all
                end
                dataset.each do |entry|
                  result << entry
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {}})
              end
            end
          end
        end
        result
      end
      #
      def user_id_available?(the_user_id)
        result = false
        if @authority
          result = @authority.user_id_available?(the_user_id)
        else
          if self.alive?
            if self.open?
              begin
                if the_user_id.to_s.size <= 256
                  if @connector[:users].filter({:user_id => (the_user_id.to_s)}).count == 0
                    result = true
                  end
                else
                  raise ArgumentError, "Oversized UserID attempted: #{the_user_id}"
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:user_id => the_user_id}})
              end
            end
          end
        end
        result
      end
      #
      def user_exist?(the_user_id)
        result = false
        if @authority
          result = @authority.user_exist?(the_user_id)
        else
          if self.alive?
            if self.open?
              begin
                if ::GxG::valid_uuid?(the_user_id)
                  if @connector[:users].filter({:uuid => (the_user_id.to_s)}).count > 0
                    result = true
                  end
                else
                  if the_user_id.to_s.size <= 256
                    if @connector[:users].filter({:user_id => (the_user_id.to_s)}).count > 0
                      result = true
                    end
                  else
                    raise ArgumentError, "Oversized UserID attempted: #{the_user_id}"
                  end
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:user_id => the_user_id}})
              end
            end
          end
        end
        result
      end
      #
      def user_credential(the_user_id="", the_password="")
        result = nil
        if @authority
          result = @authority.user_credential(the_user_id, the_password)
        else
          if self.alive?
            if self.open?
              begin
                if the_user_id.to_s.size <= 256
                  if the_password.to_s.size > 0
                    record = @connector[:users].select(:uuid, :user_id, :password_hash).where({:user_id => (the_user_id.to_s)}).first
                    if record
                      salt = record[:password_hash].split("\t")[0].to_s
                      pbkdf2 = ::Base64.decode64(record[:password_hash].split("\t")[1].to_s)
                      tester = ::OpenSSL::PKCS5::pbkdf2_hmac_sha1(the_password.to_s, salt, 1000, pbkdf2.length)
                      if pbkdf2 == tester
                        result = record[:uuid].to_sym
                      else
                        log_warn("Password attempt invalid for #{the_user_id}")
                      end
                    else
                      raise Exception, "UserID not found: #{the_user_id}"
                    end
                  else
                    raise Exception, "Empty password not supported"
                  end
                else
                  raise Exception, "Oversized UserID attempted: #{the_user_id}"
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:user_id => the_user_id}})
              end
            end
          end
        end
        result
      end
      #
      def user_create(the_user_id="", the_password="", use_credential=nil)
        result = false
        if @authority
          result = @authority.user_create(the_user_id, the_password)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if the_user_id.to_s.size <= 256
                    if the_password.to_s.size > 0
                      if self.user_id_available?(the_user_id)
                        if ::GxG::valid_uuid?(use_credential)
                          the_uuid = use_credential.to_s
                          if (@connector[:users].filter({:uuid => (the_uuid.to_s)}).count > 0)
                            raise Exception, "That credential UUID is already in use"
                          end
                        else
                          the_uuid = ::GxG::uuid_generate()
                          while (@connector[:users].filter({:uuid => (the_uuid.to_s)}).count > 0)
                            the_uuid = ::GxG::uuid_generate()
                          end
                        end
                        salt = ::SecureRandom.base64(24)
                        pbkdf2 = ::OpenSSL::PKCS5::pbkdf2_hmac_sha1(the_password, salt, 1000, 24)
                        the_pass_hash = [salt, ::Base64.strict_encode64(pbkdf2)].join("\t")
                        @connector[:users].insert({:uuid => (the_uuid), :user_id => (the_user_id.to_s), :password_hash => (the_pass_hash)})
                        result = true
                      else
                        raise Exception, "UserID not available: #{the_user_id}"
                      end
                    else
                      raise ArgumentError, "Empty password not supported"
                    end
                  else
                    raise ArgumentError, "Oversized UserID attempted: #{the_user_id}"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:user_id => the_user_id}})
                end
              end
            end
          end
        end
        result
      end
      #
      def user_update(credential=nil, user_id=nil)
        result = false
        if @authority
          result = @authority.user_update(credential, user_id)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(credential)
                    if self.user_id_available?(user_id.to_s)
                      record = @connector[:users].filter({:uuid => (credential.to_s)}).first
                      if record
                        @connector[:users].filter({:uuid => (credential.to_s)}).update({:user_id => (user_id), :version => (record[:version] + 0.0001)})
                        result = true
                      else
                        raise Exception, "User record not found"
                      end
                    else
                      log_warn("UserID is not available: #{user_id.to_s}")
                    end
                  else
                    raise ArgumentError, "You must supply a valid user credential (as a String or Symbol)"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:credential => credential, :user_id => user_id}})
                end
              end
            end
          end
        end
        result
      end
      #
      def user_set_password(credential=nil, old_password="", new_password="")
        result = false
        if @authority
          result = @authority.user_set_password(credential, old_password, new_password)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(credential)
                    if new_password.to_s.size > 0
                      if @connector[:users].filter({:uuid => (credential.to_s)}).count > 0
                        record = @connector[:users].filter({:uuid => (credential.to_s)}).first
                        if record
                          if self.user_credential(record[:user_id], old_password).to_s == credential.to_s
                            salt = ::SecureRandom.base64(24)
                            pbkdf2 = ::OpenSSL::PKCS5::pbkdf2_hmac_sha1(new_password, salt, 1000, 24)
                            the_pass_hash = [salt, ::Base64.strict_encode64(pbkdf2)].join("\t")
                            @connector[:users].filter({:uuid => (credential.to_s)}).update({:password_hash => (the_pass_hash), :version => (BigDecimal(record[:version].to_s) + 0.0001)})
                            result = true
                          else
                            log_warn("Invalid password change attempted for #{credential}")
                          end
                        else
                          raise Exception, "Could not retrieve user record: #{credential}"
                        end
                      else
                        raise Exception, "No user with that credential exists"
                      end
                    else
                      raise ArgumentError, "Empty password not supported"
                    end
                  else
                    raise ArgumentError, "Invalid credential argument: #{credential}"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:credential => credential}})
                end
              end
            end
          end
        end
        result
      end
      #
      def user_destroy(credential=nil)
        result = false
        if @authority
          result = @authority.user_destroy(credential)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(credential)
                    if @connector[:users].filter({:uuid => (credential.to_s)}).count > 0
                      the_list = self.db_list()
                      the_list << (self)
                      the_list.each do |the_db|
                        the_db.connector()[:permissions].filter({:credential => (credential.to_s)}).delete
                        the_db.connector()[:user_roles].filter({:user_uuid => (credential.to_s)}).delete
                      end
                      @connector[:users].filter({:uuid => (credential.to_s)}).delete
                      result = true
                    end
                  else
                    raise ArgumentError, "Invalid credential argument: #{credential}"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:credential => credential}})
                end
              end
            end
          end
        end
        result
      end
      #
      def user_fetch(search_options={})
        result = nil
        if @authority
          result = @authority.user_fetch(search_options)
        else
          if self.alive?
            if self.open?
              begin
                result = @connector[:users].filter(search_options).first
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:credential => (credential)}})
              end
            end
          end
        end
        result
      end
      #
      def user_roles(credential=nil)
        result = []
        if @authority
          result = @authority.user_roles(credential)
        else
          if self.alive?
            if self.open?
              begin
                if ::GxG::valid_uuid?(credential)
                  memberships = @connector[:user_roles].select(:role_uuid).where({:user_uuid => (credential.to_s)})
                  pull_list = []
                  memberships.each do |record|
                    unless pull_list.find_index(record[:role_uuid].to_sym)
                      pull_list << record[:role_uuid].to_sym
                    end
                  end
                  pull_list.each do |role_uuid|
                    record = @connector[:roles].filter({:uuid => (role_uuid.to_s)})
                    if record
                      result << {:credential => (role_uuid), :title => (record[:title]), :seo => (record[:seo])}
                    end
                  end
                else
                  raise ArgumentError, "You must supply a valid user credential (as a String or Symbol)"
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:credential => (credential)}})
              end
            end
          end
        end
        result
      end
      #
      def role_manifest()
        result = []
        #
        if @authority
          result = @authority.roles()
        else
          if self.alive?
            if self.open?
              @connector[:roles].all.each do |record|
                result << {:uuid => record[:uuid].to_s.to_sym, :title => record[:title], :seo => record[:seo], :version => BigDecimal(record[:version].to_s)}
              end
            end
          end
        end
        #
        result
      end
      #
      def role_exist?(credential=nil)
        result = nil
        if @authority
          result = @authority.role_exist?(credential)
        else
          if self.alive?
            if self.open?
              if ::GxG::valid_uuid?(credential)
                if @connector[:roles].filter({:uuid => (credential.to_s)}).count > 0
                  result = true
                end
              else
                if @connector[:roles].filter({:title => (credential.to_s)}).count > 0
                  result = true
                end
              end
            end
          end
        end
        result
      end
      #
      def role_create(title="", seo="")
        result = nil
        if @authority
          result = @authority.role_create(title,seo)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  #
                  if title.to_s.size <= 256
                    #
                    if title.to_s.size == 0
                      raise ArgumentError, "You MUST supply a title for the role."
                    end
                    unless seo.to_s.size <= 256
                      raise ArgumentError, "Oversized SEO attempted (256 Character Limit): #{seo}"
                    end
                    if seo.to_s.size == 0
                      seo = title.downcase.gsub(" ","_")[0..255]
                    end
                    the_uuid = ::GxG::uuid_generate()
                    while (@connector[:roles].filter({:uuid => (the_uuid.to_s)}).count > 0)
                      the_uuid = ::GxG::uuid_generate()
                    end
                    @connector[:roles].insert({:uuid => (the_uuid.to_s), :title => (title.to_s), :seo => (seo.to_s)})
                    result = the_uuid.to_sym
                  else
                    raise ArgumentError, "Oversized title attempted (256 Character Limit): #{title}"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:title => (title), :seo => (seo)}})
                end
              end
            end
          end
        end
        result
      end
      #
      def role_update(role_uuid=nil, data={})
        # data: :title, :seo
        result = false
        if @authority
          result = @authority.role_update(role_uuid,data)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  unless data.is_a?(::Hash)
                    raise Exception, "Update data must be passed in a Hash"
                  end
                  if ::GxG::valid_uuid?(role_uuid)
                    record = @connector[:roles].filter({:uuid => (role_uuid.to_s)}).first
                    if record
                      the_title = (data[:title] || record[:title].to_s)
                      the_seo = (data[:seo] || the_title.downcase.gsub(" ", "_"))
                      #
                      @connector[:roles].filter({:uuid => (role_uuid.to_s)}).update({:title => (the_title), :seo => (the_seo), :version => (BigDecimal(record[:version].to_s) + 0.0001)})
                      result = true
                    else
                      raise Exception, "Attempted to update a non-existent role: #{role_uuid}"
                    end
                  else
                    raise ArgumentError, "You must specify a valid role UUID (as a String or Symbol)"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:role_uuid => (role_uuid), :data => (data)}})
                end
              end
            end
          end
        end
        result
      end
      #
      def role_destroy(role_uuid=nil)
        result = false
        if @authority
          result = @authority.role_destroy(role_uuid)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(role_uuid)
                    # cannot destroy if still linked as group's default role
                    record = @connector[:roles].filter({:uuid => (role_uuid.to_s)}).first
                    if record
                      the_list = self.db_list()
                      the_list << (self)
                      the_list.each do |the_db|
                        the_db.connector()[:permissions].filter({:credential => (role_uuid.to_s)}).delete
                        the_db.connector()[:user_roles].filter({:role_uuid => (role_uuid.to_s)}).delete
                      end
                      @connector[:roles].filter({:uuid => (role_uuid.to_s)}).delete
                      result = true
                    end
                  else
                    raise ArgumentError, "You must specify a valid role UUID (as a String or Symbol)"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:role_uuid => (role_uuid)}})
                end
              end
            end
          end
        end
        result
      end
      #
      def role_add_user(role_uuid=nil, credential=nil)
        result = false
        if @authority
          result = @authority.role_add_user(role_uuid, credential)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(role_uuid)
                    if ::GxG::valid_uuid?(credential)
                      if @connector[:user_roles].filter({:role_uuid => (role_uuid.to_s), :user_uuid => (credential.to_s)}).count == 0
                        @connector[:user_roles].insert({:role_uuid => (role_uuid.to_s), :user_uuid => (credential.to_s)})
                      end
                      result = true
                    else
                      raise ArgumentError, "You must specify a valid user credential UUID (as a String or Symbol)"
                    end
                  else
                    raise ArgumentError, "You must specify a valid role UUID (as a String or Symbol)"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:role_uuid => (role_uuid), :credential => (credential)}})
                end
              end
            end
          end
        end
        result
      end
      #
      def role_remove_user(role_uuid=nil, credential=nil)
        result = false
        if @authority
          result = @authority.role_remove_user(role_uuid, credential)
        else
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                begin
                  if ::GxG::valid_uuid?(role_uuid)
                    if ::GxG::valid_uuid?(credential)
                      if @connector[:user_roles].filter({:role_uuid => (role_uuid.to_s), :user_uuid => (credential.to_s)}).count > 0
                        @connector[:user_roles].filter({:role_uuid => (role_uuid.to_s), :user_uuid => (credential.to_s)}).delete
                      end
                      result = true
                    else
                      raise ArgumentError, "You must specify a valid user credential UUID (as a String or Symbol)"
                    end
                  else
                    raise ArgumentError, "You must specify a valid role UUID (as a String or Symbol)"
                  end
                rescue Exception => the_error
                  log_error({:error => the_error, :parameters => {:role_uuid => (role_uuid), :credential => (credential)}})
                end
              end
            end
          end
        end
        result
      end
      #
      def role_member?(role_uuid=nil, credential=nil)
        result = false
        if @authority
          result = @authority.role_member?(role_uuid, credential)
        else
          if self.alive?
            if self.open?
              begin
                if ::GxG::valid_uuid?(role_uuid)
                  if ::GxG::valid_uuid?(credential)
                    if @connector[:user_roles].filter({:role_uuid => (role_uuid.to_s), :user_uuid => (credential.to_s)}).count > 0
                      result = true
                    end
                  else
                    raise ArgumentError, "You must specify a valid user credential UUID (as a String or Symbol)"
                  end
                else
                  raise ArgumentError, "You must specify a valid role UUID (as a String or Symbol)"
                end
              rescue Exception => the_error
                log_error({:error => the_error, :parameters => {:role_uuid => (role_uuid), :credential => (credential)}})
              end
            end
          end
        end
        result
      end
      #
      def role_members(role_uuid=nil)
        result = []
        if @authority
          result = @authority.role_members(role_uuid)
        else
          if self.alive?
            if self.open?
              if GxG::valid_uuid?(role_uuid)
                @connector[:user_roles].filter({:role_uuid => (role_uuid.to_s)}).each do |the_record|
                  unless result.include?(the_record[:user_uuid].to_s.to_sym)
                    result << the_record[:user_uuid].to_s.to_sym
                  end
                end
              end
            end
          end
        end
        result
      end
      #
      def role_fetch(search_options={})
        result = nil
        if @authority
          result = @authority.role_fetch(search_options)
        else
          if self.alive?
            if self.open?
              result = @connector[:roles].filter(search_options).first
            end
          end
        end
        result
      end
      #
      # ### Raw Permission Handling methods
      def element_permissions(table=:unspecified, dbid=0, options={})
        result = []
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless dbid.is_a?(::Integer)
            raise ArgumentError, "dbid must be specified with a Integer"
          end
          unless options.is_a?(::Hash)
            raise ArgumentError, "options must be specified with a Hash"
          end
          credential = options[:credential]
          if credential
            unless ::GxG::valid_uuid?(credential)
              raise ArgumentError, "This option requires a valid credential UUID (as a String or Symbol)"
            end
          end
          if table.is_a?(::Integer)
            table = ::GxG::Database::Database::element_table_by_index(table)
          end
          # Review : change in permission policy
          # if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
          if [:element_array, :element_hash].include?(table)
            if credential
              list = @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid), :credential => (credential.to_s)})
            else
              list = @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid)})
            end
            list.each do |record|
              # [:execute, :rename, :move, :destroy, :create, :write, :read]
              entry = {:credential => (record[:credential].to_sym), :table => (record[:element_table].to_sym), :dbid => (record[:elementid]), :permissions => {}}
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if record[(the_permission)] == 1
                  entry[:permissions][(the_permission)] = true
                else
                  entry[:permissions][(the_permission)] = false
                end
              end
              result << entry
            end
          else
            raise ArgumentError, "Invalid table specified"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid), :options => (options)}})
        end
        result
      end
      #
      def revoke_element_permissions(table=:unspecified, dbid=0, credential=nil)
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless dbid.is_a?(::Integer)
            raise ArgumentError, "dbid must be specified with a Integer"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "This option requires a valid credential UUID (as a String or Symbol)"
          end
          if table.is_a?(::Integer)
            table = ::GxG::Database::Database::element_table_by_index(table)
          end
          # Review : change in permission policy
          # if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
          if [:element_array, :element_hash].include?(table)
            @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid), :credential => (credential.to_s)}).delete
            result = true
          else
            raise ArgumentError, "Invalid table specified"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid), :options => (options)}})
        end
        result
      end
      #
      #
      def element_permissions_manifest(table=:unspecified, dbid=0, options={})
        result = []
        self.element_permissions(table,dbid,options).each do |entry|
          the_record = {:credential => nil, :permissions => {}, :details => {}}
          #
          the_record[:credential] = entry[:credential]
          the_record[:permissions] = entry[:permissions]
          if self.role_exist?(entry[:credential])
            role = self.role_fetch({:uuid => entry[:credential].to_s})
            group = self.group_fetch({:uuid => role[:group_uuid].to_s})
            the_record[:details][:role_title] = role[:title]
            the_record[:details][:group] = group[:uuid].to_s.to_sym
            the_record[:details][:group_title] = group[:title]
          else
            if self.user_exist?(entry[:credential])
              user = self.user_fetch({:uuid => entry[:credential].to_s})
              the_record[:details][:user_title] = user[:user_id]
            else
              log_warn("Invalid User Credential Detected: #{entry[:credential].to_s.to_sym.inspect}")
              the_record[:details][:user_title] = "Invalid User Credential #{entry[:credential].to_s.to_sym.inspect} !"
            end
          end
          result << the_record
        end
        result
      end
      #
      def element_permissions_by_uuid(the_uuid=nil,options={})
        result = []
        begin
          if self.alive?
            if self.open?
              found = @connector[:element_hash].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
              if found
                result = self.element_permissions_manifest(:element_hash,(found[:dbid]),options)
              else
                found = @connector[:element_array].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
                if found
                  result = self.element_permissions_manifest(:element_array,(found[:dbid]),options)
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:uuid => (the_uuid)}})
        end
        result
      end
      #
      def revoke_permissions_by_uuid(the_uuid=nil, credential=nil)
        result = false
        begin
          if self.alive?
            if self.open?
              found = @connector[:element_hash].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
              if found
                result = self.revoke_element_permissions(:element_hash,(found[:dbid]),credential)
              else
                found = @connector[:element_array].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
                if found
                  result = self.revoke_element_permissions(:element_array,(found[:dbid]),credential)
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:uuid => (the_uuid)}})
        end
        result
      end
      #
      def assign_element_permission(table=:unspecified, dbid=0, credential=nil, permissions={})
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless dbid.is_a?(::Integer)
            raise ArgumentError, "dbid must be specified with a Integer"
          end
          unless permissions.is_a?(::Hash)
            raise ArgumentError, "permissions must be specified with a Hash"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          if table.is_a?(::Integer)
            table = ::GxG::Database::Database::element_table_by_index(table)
          end
          # Review : change in permission policy
          # if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
          if [:element_array, :element_hash].include?(table)
            record = @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid), :credential => (credential.to_s)}).first
            if record
              # update
              the_update = {:execute => 0, :rename => 0, :move => 0, :destroy => 0, :create => 0, :write => 0, :read => 0}
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if record[(the_permission)] == 1
                  the_update[(the_permission)] = 1
                end
              end
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if permissions[(the_permission)].is_a?(::TrueClass)
                  the_update[(the_permission)] = 1
                end
                if permissions[(the_permission)].is_a?(::FalseClass)
                  the_update[(the_permission)] = 0
                end
              end
              the_update[:version] = record[:version] + 0.0001
              @connector[:permissions].filter({:dbid => (record[:dbid])}).update(the_update)
            else
              # create
              new_record = {:credential => (credential.to_s), :element_table => (table.to_s), :elementid => (dbid), :execute => 0, :rename => 0, :move => 0, :destroy => 0, :create => 0, :write => 0, :read => 0}
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if permissions[(the_permission)]
                  new_record[(the_permission)] = 1
                end
              end
              @connector[:permissions].insert(new_record)
            end
            result = true
          else
            raise ArgumentError, "Invalid table specified"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid), :credential => (credential), :permissions => (permissions)}})
        end
        result
      end
      #
      def extend_element_permissions(source_table=:unspecified, source_dbid=0, dest_table=:unspecified, dest_dbid=0)
        permissions = self.element_permissions(source_table, source_dbid)
        permissions.each do |entry|
          if [:persisted_array, :persisted_hash].include?(dest_table)
            self.assign_element_permission(dest_table, dest_dbid, entry[:credential], entry[:permissions])
          end
        end
      end
      #
      def remove_element_permissions(table=:unspecified, dbid=0, options={})
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless dbid.is_a?(::Integer)
            raise ArgumentError, "dbid must be specified with a Integer"
          end
          unless options.is_a?(::Hash)
            raise ArgumentError, "permissions must be specified with a Hash"
          end
          credential = options[:credential]
          if credential
            unless ::GxG::valid_uuid?(credential)
              raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
            end
          end
          if table.is_a?(::Integer)
            table = ::GxG::Database::Database::element_table_by_index(table)
          end
          # Review : change in permission policy
          # if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
          if [:element_array, :element_hash].include?(table)
            if credential
              @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid), :credential => (credential.to_s)}).delete
            else
              @connector[:permissions].filter({:element_table => (table.to_s), :elementid => (dbid)}).delete
            end
            result = true
          else
            raise ArgumentError, "Invalid table specified"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid), :options => (options)}})
        end
        result
      end
      # ### Effective Permission Handling methods
      # ### VFS File permission mappings
      def vfs_permission_exist?(file_id=nil, credential=nil)
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "file_id must be specified with a String"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          #
          if @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => credential.to_s}).count > 0
            result = true
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      #
      def vfs_permission(file_id=nil, credential=nil)
        result = []
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "dbid must be specified with a String"
          end
          if credential
            unless ::GxG::valid_uuid?(credential)
              raise ArgumentError, "This option requires a valid credential UUID (as a String or Symbol)"
            end
          end
          #
          if credential
            list = @connector[:file_permissions].filter({:file_id => (file_id.to_s), :credential => (credential.to_s)})
          else
            list = @connector[:file_permissions].filter({:file_id => (file_id.to_s)})
          end
          list.each do |record|
            # [:execute, :rename, :move, :destroy, :create, :write, :read]
            entry = {:credential => (record[:credential].to_sym), :permissions => {}}
            [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
              if record[(the_permission)] == 1
                entry[:permissions][(the_permission)] = true
              else
                entry[:permissions][(the_permission)] = false
              end
            end
            result << entry
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      #
      def vfs_permission_manifest(file_id=nil, credential=nil)
        result = []
        self.vfs_permission(file_id, credential).each do |entry|
          the_record = {:credential => nil, :permissions => {}, :details => {}}
          #
          the_record[:credential] = entry[:credential]
          the_record[:permissions] = entry[:permissions]
          if self.role_exist?(entry[:credential])
            role = self.role_fetch({:uuid => entry[:credential].to_s})
            the_record[:details][:role_title] = role[:title]
          else
            if self.user_exist?(entry[:credential])
              user = self.user_fetch({:uuid => entry[:credential].to_s})
              the_record[:details][:user_title] = user[:user_id]
            else
              log_warn("Invalid User Credential Detected: #{entry[:credential].to_s.to_sym.inspect}")
              the_record[:details][:user_title] = "Invalid User Credential #{entry[:credential].to_s.to_sym.inspect} !"
            end
          end
          result << the_record
        end
        result
      end
      #
      def effective_vfs_permission(file_id=nil, credential=nil)
        result = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "file_id must be specified with a String"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          # ### VFS Permissions
          raw_permissions = []
          credentials = ["00000000-0000-4000-0000-000000000000"]
          if self.user_exist?(credential)
            credentials << credential
            role_list = self.user_roles(credential)
            role_list.each do |entry|
              credentials << entry[:credential]
            end
            #
          else
            if self.role_exist?(credential)
              credentials << credential
            else
              raise ArgumentError, "Invalid credential.  It is neither a user nor a role UUID"
            end
          end
          credentials.each do |entry|
            manifest = @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => (entry.to_s)})
            manifest.each do |record|
              new_permission = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if record[(the_permission)] == 1
                  new_permission[(the_permission)] = true
                end
              end
              raw_permissions << new_permission
            end
          end
          raw_permissions.each do |entry|
            [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
              if entry[(the_permission)]
                result[(the_permission)] = true
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      #
      def create_vfs_permission(file_id=nil, credential=nil, permission={:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false})
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "file_id must be specified with a String"
          end
          unless permission.is_a?(::Hash)
            raise ArgumentError, "permission must be specified with a Hash"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          #
          record = @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => credential.to_s}).first
          if record
            update = true
            dbid = record.delete(:dbid)
          else
            update = false
            dbid = nil
            record = {:file_id => file_id.to_s, :credential => credential.to_s, :execute => 0, :rename => 0, :move => 0, :destroy => 0, :create => 0, :write => 0, :read => 0}
          end
          permission.keys.each do |the_permission_key|
            if permission[(the_permission_key)] == true
              record[(the_permission_key)] = 1
            else
              record[(the_permission_key)] = 0
            end
          end
          if update == true
            @connector[:file_permissions].filter({:dbid => dbid}).update(record)
          else
            @connector[:file_permissions].insert(record)
          end
          result = true
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      #
      def update_vfs_permission(file_id=nil, credential=nil, permission={:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false})
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "file_id must be specified with a String"
          end
          unless permission.is_a?(::Hash)
            raise ArgumentError, "permission must be specified with a Hash"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          #
          record = @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => credential.to_s}).first
          if record
            update = true
            dbid = record.delete(:dbid)
          else
            update = false
            dbid = nil
            record = {:file_id => file_id.to_s, :credential => credential.to_s, :execute => 0, :rename => 0, :move => 0, :destroy => 0, :create => 0, :write => 0, :read => 0}
            # Review : should we update the version ??
          end
          permission.keys.each do |the_permission_key|
            if permission[(the_permission_key)] == true
              record[(the_permission_key)] = 1
            else
              record[(the_permission_key)] = 0
            end
          end
          if update == true
            @connector[:file_permissions].filter({:dbid => dbid}).update(record)
          else
            @connector[:file_permissions].insert(record)
          end
          result = true
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      #
      def destroy_vfs_permission(file_id=nil, credential=nil)
        result = false
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless file_id.is_a?(::String)
            raise ArgumentError, "file_id must be specified with a String"
          end
          # ### Review : make more efficient
          if credential
            unless ::GxG::valid_uuid?(credential)
              raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
            end
            record = @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => credential.to_s}).first
            if record
              @connector[:file_permissions].filter({:file_id => file_id.to_s, :credential => credential.to_s}).delete
            end
          else
            record = @connector[:file_permissions].filter({:file_id => file_id.to_s}).first
            if record
              @connector[:file_permissions].filter({:file_id => file_id.to_s}).delete
            end
          end
          result = true
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:file_id => (file_id), :credential => (credential)}})
        end
        result
      end
      # ### DB Objects
      def effective_element_permission(table=:unspecified, dbid=0, credential=nil)
        result = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
        begin
          unless self.alive?
            raise Exception, "Database inactive"
          end
          unless self.open?
            raise Exception, "Database not available"
          end
          unless dbid.is_a?(::Integer)
            raise ArgumentError, "dbid must be specified with a Integer"
          end
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must specify a valid credential UUID (as a String or Symbol)"
          end
          if table.is_a?(::Integer)
            table = ::GxG::Database::Database::element_table_by_index(table)
          end
          # Review : change in permission policy
          # if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
          if [:element_array, :element_hash].include?(table)
            # is credential a user or role?
            raw_permissions = []
            # Include PUBLIC credential
            credentials = ["00000000-0000-4000-0000-000000000000"]
            #
            if self.user_exist?(credential)
              credentials << credential
              role_list = self.user_roles(credential)
              role_list.each do |entry|
                credentials << entry[:credential]
              end
              #
            else
              if self.role_exist?(credential)
                credentials << credential
              else
                raise ArgumentError, "Invalid credential.  It is neither a user nor a role UUID"
              end
            end
            credentials.each do |entry|
              manifest = @connector[:permissions].filter({:credential => (entry.to_s), :element_table => (table.to_s), :elementid => (dbid)})
              manifest.each do |record|
                new_permission = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
                [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                  if record[(the_permission)] == 1
                    new_permission[(the_permission)] = true
                  end
                end
                raw_permissions << new_permission
              end
            end
            permission = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
            raw_permissions.each do |entry|
              [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
                if entry[(the_permission)]
                  permission[(the_permission)] = true
                end
              end
            end
            db_limits = self.db_permissions()
            [:execute, :rename, :move, :destroy, :create, :write, :read].each do |the_permission|
              if db_limits[(the_permission)] and permission[(the_permission)]
                result[(the_permission)] = true
              end
            end
            #
          else
            raise ArgumentError, "Invalid table specified"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid), :credential => (credential)}})
        end
        result
      end
      #
      def  effective_uuid_permission(uuid=nil, credential=nil)
        result = nil
        begin
          if self.alive?
            if self.open?
              address = nil
              record = @connector[:element_hash].filter({:uuid => (uuid.to_s)}).first
              if record
                address = {:database => self, :table => :element_hash, :dbid => (record[:dbid])}
              else
                record = @connector[:element_array].filter({:uuid => (uuid.to_s)}).first
                if record
                  address = {:database => self, :table => :element_array, :dbid => (record[:dbid])}
                end
              end
              if address
                result = self.effective_element_permission(address[:table], address[:dbid], credential)
              else
                # ### Review : Experimental Code - attempt to seemlessly integrate dbs of different roles into in-memory structures.
                already_checked = [(self)]
                ::GxG::DB[:roles].each_pair do |the_db_role, the_database|
                  unless already_checked.include?(the_database)
                    record = the_database.connector[:element_hash].filter({:uuid => (uuid.to_s)}).first
                    if record
                      address = {:database => the_database, :table => :element_hash, :dbid => (record[:dbid])}
                      result = the_database.effective_element_permission(address[:table], address[:dbid], credential)
                      break
                    else
                      record = the_database.connector[:element_array].filter({:uuid => (uuid.to_s)}).first
                      if record
                        address = {:database => the_database, :table => :element_array, :dbid => (record[:dbid])}
                        result = the_database.effective_element_permission(address[:table], address[:dbid], credential)
                        break
                      end
                    end
                    already_checked << the_database
                  end
                end
                # 
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:uuid => (uuid), :credential => (credential)}})
        end
        result
      end
      # ### Data Handling methods
      #
      def element_exists?(the_table=:unspecified, the_dbid=0)
        result = false
        if the_table.is_a?(::Integer)
          the_table = ::GxG::Database::Database::element_table_by_index(the_table)
        end
        if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(the_table)
          begin
            record = @connector[(the_table)].select(:dbid).where({:dbid => (the_dbid)}).first
            if record
              result = true
            end
          rescue Exception => the_error
            log_error({:error => the_error, :parameters => {:table => (the_table), :dbid => (the_dbid)}})
          end
        end
        result
      end
      #
      def element_retrieve(the_table=:unspecified, the_filter={}, options={})
        result = []
        begin
          if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :text_page, :element_binary,:binary_page, :element_array, :element_hash].include?(the_table)
            #
            if the_filter.is_a?(::Hash)
              if options[:order]
                raw_result = @connector[(the_table)].filter(the_filter).order(options[:order])
              else
                raw_result = @connector[(the_table)].filter(the_filter)
              end
              # Review : UTF-8 Encoding Error Fix
              if options[:single_record] == true
                result = raw_result.first
                # utf8 fix
                if the_table == :text_page
                  if result[:content].is_a?(::String)
                    if result[:content].base64?
                      result[:content] = result[:content].decode64
                    end
                  end
                end
                #
              else
                # utf8 fix
                raw_result.each do |the_record|
                  if the_record[:content].is_a?(::String)
                    if the_record[:content].base64?
                      the_record[:content] = the_record[:content].decode64
                    end
                  end
                  result << the_record
                end
                # result = raw_result
              end
              #
            else
              raise ArguementError, "You MUST provide a record selection filter as a Hash. "
            end
          else
            raise ArgumentError, "The table specified is unknown - Check your code."
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => the_table, :filter => the_filter, :options => options}})
        end
        result
      end
      #
      def element_create(the_table=:unspecified, the_record=nil)
        # Review : rewrite - in use
        result = nil
        begin
          unless the_table.is_a?(::Symbol)
            raise ArgumentError, "You MUST provide the table specifier as a Symbol."
          end
          unless the_record.is_a?(::Hash)
            raise ArgumentError, "You MUST provide a record in the form of a Hash."
          end
          if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :text_page, :element_binary, :binary_page, :element_array, :element_hash].include?(the_table)
            # Review : UTF8 fix
            begin
              result = @connector[(the_table)].insert(the_record)
            rescue Exception
              if the_table == :text_page
                the_record[:content] = the_record[:content].encode64
              end
              result = @connector[(the_table)].insert(the_record)
            end
          else
            raise ArgumentError, "The table specified is unknown - Check your code."
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (the_table), :record => (the_record)}})
        end
        result
      end
      #
      def element_update(the_table=:unspecified, the_filter={}, the_record=nil)
        result = false
        begin
          unless the_table.is_a?(::Symbol)
            raise ArgumentError, "You MUST provide the table specifier as a Symbol."
          end
          unless the_filter.is_a?(::Hash)
            raise ArgumentError, "You MUST provide a selection filter in the form of a Hash."
          end
          unless the_record.is_a?(::Hash)
            raise ArgumentError, "You MUST provide a record in the form of a Hash."
          end
          if [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :text_page, :element_binary, :binary_page, :element_array, :element_hash].include?(the_table)
            # Review : shim to eliminate UTF-8 encoding errors
            begin
              @connector[(the_table)].filter(the_filter).update(the_record)
            rescue Exception
              if the_table == :text_page
                the_record[:content] = the_record[:content].encode64
              end
              @connector[(the_table)].filter(the_filter).update(the_record)
            end
            result = true
          else
            raise ArgumentError, "The table specified is unknown - Check your code."
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => the_table, :filter => the_filter, :record => the_record}})
        end
        result
      end
      #
      def structure_detach(the_uuid=nil)
        if ::GxG::valid_uuid?(the_uuid)
          record = self.structural_link(the_uuid)
          if record
            record[:database].connector()[(record[:table])].filter({:dbid => record[:dbid]}).update({:element => "element_boolean", :element_boolean => -1, :element_hash_uuid => "", :element_array_uuid => ""})
            true
          else
            false
          end
        else
          false
        end
      end
      #
      def structural_link(the_uuid=nil)
        # Review : rewrite - in use
        result = nil
        if ::GxG::valid_uuid?(the_uuid)
          search_queue = [(self)]
          ::GxG::DB[:roles].each_pair do |the_role, the_database|
            unless search_queue.include?(the_database)
              search_queue << the_database
            end
          end
          search_queue.each do |the_database|
            found = the_database.connector()[:hash_properties].filter({:element_hash_uuid => the_uuid.to_s}).first
            if found
              result = {:database => the_database, :table => :hash_properties, :dbid => found[:dbid]}
              break
            end
            found = the_database.connector()[:hash_properties].filter({:element_array_uuid => the_uuid.to_s}).first
            if found
              result = {:database => the_database, :table => :hash_properties, :dbid => found[:dbid]}
              break
            end
            found = the_database.connector()[:array_elements].filter({:element_hash_uuid => the_uuid.to_s}).first
            if found
              result = {:database => the_database, :table => :hash_properties, :dbid => found[:dbid]}
              break
            end
            found = the_database.connector()[:array_elements].filter({:element_array_uuid => the_uuid.to_s}).first
            if found
              result = {:database => the_database, :table => :hash_properties, :dbid => found[:dbid]}
              break
            end
          end
        end
        result
      end
      #      
      def structure_attached?(the_uuid=nil)
        # Review : rewrite - in use
        result = false
        record = self.structural_link(the_uuid)
        if record
          result = true
        end
        result
      end
      #
      def element_in_use?(db_table=:unspecified, dbid = 0)
        # Review : rewrite - in use for now.
        # Review : rewrite - todo (alter to reflect the new architecture : perhaps limit to structures only)
        unless db_table.is_any?(::Integer, ::Symbol)
          raise ArgumentError, "Table needs to be specified as a Symbol, or a table code Integer"
        end
        unless dbid.is_a?(::Integer)
          raise ArgumentError, "Record ID needs to be specified with an Integer"
        end
        result = false
        begin
          if db_table == :element_hash || db_table == :element_array
            # Review : make more efficient in later revs of this.
            the_record = @connector[(db_table)].filter({:dbid => (dbid)}).select(:uuid).first
            if the_record
              if @connector[:hash_properties].filter({:element_hash_uuid => the_record[:uuid]}).count > 0 || @connector[:array_elements].filter({:element_array_uuid => the_record[:uuid]}).count > 0
                result = true
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table_code => (db_table), :dbid => (dbid)}})
        end
        result
      end
      #
      def element_parent_address(the_table=:unspecified, the_dbid=0)
        result = nil
        if self.element_in_use?(the_table,the_dbid)
          begin
            link = @connector[:hash_links].select(:parent_uuid).where({:element => (::GxG::Database::Database::element_table_index(the_table)), :elementid => (the_dbid)}).first
            if link
              record = @connector[:element_hash].select(:dbid).where({:uuid => link[:parent_uuid]}).first
              if record
                result = {:table => :element_hash, :dbid => (record[:dbid])}
              end
            else
              link = @connector[:array_links].select(:parent_uuid).where({:element => (::GxG::Database::Database::element_table_index(the_table)), :elementid => (the_dbid)}).first
              if link
                record = @connector[:element_array].select(:dbid).where({:uuid => link[:parent_uuid]}).first
                if record
                  result = {:table => :element_array, :dbid => (record[:dbid])}
                end
              end
            end
          rescue Exception => the_error
            log_error({:error => the_error, :parameters => {:table => (the_table), :dbid => (the_dbid)}})
          end
        end
        result
      end
      #
      def element_manifest(the_table=:unspecified, the_dbid=0, everything=false)
        # Review : rewrite - in use
        # returns an Array of tables and dbid pairs and sub-item pairs if they exist
        result = []
        #
        begin
          unless the_dbid > 0
            raise ArgumentError, "dbid specified must be greater than zero"
          end
          case the_table
          when :element_text
            the_record = @connector[:element_text].select(:uuid, :dbid).where({:dbid => (the_dbid)}).first
            if the_record
              result << {:table => :element_text, :dbid => the_record[:dbid]}
              if everything
                the_pages = @connector[:text_page].select(:dbid, :ordinal).where({:parent_uuid => (the_record[:uuid])}).order(:ordinal)
                the_pages.each do |entry|
                  result << {:table => :text_page, :dbid => entry[:dbid]}
                end
              end
            end
          when :element_binary
            the_record = @connector[:element_binary].select(:uuid, :dbid).where({:dbid => (the_dbid)}).first
            if the_record
              result << {:table => :element_binary, :dbid => the_record[:dbid]}
              if everything
                the_pages = @connector[:binary_page].select(:dbid, :ordinal).where({:parent_uuid => (the_record[:uuid])}).order(:ordinal)
                the_pages.each do |entry|
                  result << {:table => :binary_page, :dbid => entry[:dbid]}
                end
              end
            end
          when :element_array, :element_hash
            record_db = [{:table => the_table, :dbid => the_dbid}]
            while record_db.size > 0 do
              item = record_db.shift
              case item[:table]
              when :element_text
                the_record = @connector[:element_text].select(:uuid, :dbid).where({:dbid => item[:dbid]}).first
                if the_record
                  result << {:table => :element_text, :dbid => the_record[:dbid]}
                  if everything
                    the_pages = @connector[:text_page].select(:dbid, :ordinal).where({:parent_uuid => (the_record[:uuid])}).order(:ordinal)
                    the_pages.each do |entry|
                      result << {:table => :text_page, :dbid => entry[:dbid]}
                    end
                  end
                end
              when :element_binary
                the_record = @connector[:element_binary].select(:uuid, :dbid).where({:dbid => item[:dbid]}).first
                if the_record
                  result << {:table => :element_binary, :dbid => the_record[:dbid]}
                  if everything
                    the_pages = @connector[:binary_page].select(:dbid, :ordinal).where({:parent_uuid => (the_record[:uuid])}).order(:ordinal)
                    the_pages.each do |entry|
                      result << {:table => :binary_page, :dbid => entry[:dbid]}
                    end
                  end
                end
              when :element_array
                result << {:table => item[:table], :dbid => item[:dbid]}
                array_record = @connector[:element_array].select(:uuid).where({:dbid => item[:dbid]}).first
                if array_record
                  @connector[:array_elements].filter({:parent_uuid => (array_record[:uuid])}).order(:ordinal).each do |entry|
                    if entry[:element_text_uuid].size > 0
                      the_temp_record = @connector[:element_text].select(:dbid).where({:uuid => entry[:element_text_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_text, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_binary_uuid].size > 0
                      the_temp_record = @connector[:element_binary].select(:dbid).where({:uuid => entry[:element_binary_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_binary, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_array_uuid].size > 0
                      the_temp_record = @connector[:element_array].select(:dbid).where({:uuid => entry[:element_array_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_array, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_hash_uuid].size > 0
                      the_temp_record = @connector[:element_hash].select(:dbid).where({:uuid => entry[:element_hash_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_hash, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    result << {:table => :array_elements, :dbid => entry[:dbid]}
                  end
                end
              when :element_hash
                result << {:table => item[:table], :dbid => item[:dbid]}
                hash_record = @connector[:element_hash].select(:uuid).where({:dbid => item[:dbid]}).first
                if hash_record
                  @connector[:hash_properties].filter({:parent_uuid => (hash_record[:uuid])}).order(:ordinal).each do |entry|
                    if entry[:element_text_uuid].size > 0
                      the_temp_record = @connector[:element_text].select(:dbid).where({:uuid => entry[:element_text_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_text, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_binary_uuid].size > 0
                      the_temp_record = @connector[:element_binary].select(:dbid).where({:uuid => entry[:element_binary_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_binary, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_array_uuid].size > 0
                      the_temp_record = @connector[:element_array].select(:dbid).where({:uuid => entry[:element_array_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_array, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    if entry[:element_hash_uuid].size > 0
                      the_temp_record = @connector[:element_hash].select(:dbid).where({:uuid => entry[:element_hash_uuid]}).first
                      if the_temp_record
                        record_db << {:table => :element_hash, :dbid => the_temp_record[:dbid]}
                      end
                    end
                    result << {:table => :hash_properties, :dbid => entry[:dbid]}
                  end
                end
              else
                the_record = @connector[(item[:table])].select(:dbid).where({:dbid => (item[:dbid])}).first
                if the_record
                  result << {:table => item[:table], :dbid => item[:dbid]}
                end
              end
            end
            #
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (the_table), :dbid => (the_dbid)}})
        end
        result
      end
      #
      def element_destroy(credential=nil,table=:unspecified,dbid=0, options={})
        # Review : rewrite for new arch.
        # Review : rewrite - in use
        result = false
        begin
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                # if credential has :destroy permission on this element?
                if ::GxG::valid_uuid?(credential)
                  if [:persisted_array, :persisted_hash].include?(table.to_s.to_sym)
                    go_ahead = self.effective_element_permission(table, dbid, credential)[:destroy]
                  else
                    go_ahead = true
                  end
                  # xxx Quick fix : BETA: clean all this up!
                  if go_ahead
                    # Review : DB overhaul / rewrite - allow delete if object has write lock in place? I think not. (return false)
                    # Note: BETA - bring back read-locks? it was 9x slower with them ... not sure.
                    elements = self.element_manifest(table, dbid, false)
                    elements.each do |entry|
                      #
                      unless self.element_in_trash?(entry[:table], entry[:dbid])
                        @connector[:trash].insert({:element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                      end
                      #
                      #if @connector[:element_locks].filter({:type => "read", :element_table => entry[:table].to_s, :elementid => entry[:dbid]}).count > 0
                        # put in trash
                        #unless self.element_in_trash?(entry[:table], entry[:dbid])
                          #@connector[:trash].insert({:element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                        #end
                      #else
                        # delete now
                        #manifest = self.element_manifest(entry[:table], entry[:dbid], true)
                        #manifest.each do |item|
                          #@connector[:permissions].filter({:element_table => (item[:table].to_s), :elementid => (item[:dbid])}).delete
                          #@connector[(item[:table])].filter({:dbid => item[:dbid]}).delete
                        #end
                      #end
                    end
                    result = true
                  else
                    raise Exception, "You do not have permission to destory this element"
                  end
                else
                  raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:credential => (credential), :table => (table), :dbid => (dbid)}})
        end
        result
      end
      #
      def destroy_by_uuid(credential=nil, the_uuid=nil)
        # Review : rewrite - in use
        # element_destroy(credential=nil,table=:unspecified,dbid=0, options={})
        # .effective_uuid_permission(data["location"].to_s.to_sym,@credential)
        result = false
        begin
          if self.alive?
            if self.open?
              if self.db_permissions()[:destroy] == true
                if ::GxG::valid_uuid?(credential)
                  found = @connector[:element_hash].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
                  if found
                    self.element_destroy(credential, :element_hash,(found[:dbid]))
                    result = true
                  else
                    found = @connector[:element_array].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
                    if found
                      self.element_destroy(credential, :element_array,(found[:dbid]))
                      result = true
                    end
                  end
                else
                  raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:credential => (credential), :uuid => (the_uuid)}})
        end
        result
      end
      #
      def element_byte_size(table=:unspecified, dbid=0)
        #
        result = 0
        begin
          if self.alive?
            if self.open?
              migration = self.db_migration()
              elements = self.element_manifest(table, dbid, true)
              elements.each do |entry|
                table_definition = migration[(entry[:table])]
                if table_definition
                  table_definition.keys.each do |the_field|
                    result += table_definition[(the_field)][:bytes].to_i
                  end
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid)}})
        end
        result
      end
      #
      def byte_size_by_uuid(the_uuid=nil)
        result = 0
        begin
          if self.alive?
            if self.open?
              found = @connector[:element_hash].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
              if found
                result += self.element_byte_size(:element_hash,(found[:dbid]))
              else
                found = @connector[:element_array].select(:dbid, :uuid).filter({:uuid => the_uuid.to_s}).first
                if found
                  result += self.element_byte_size(:element_array,(found[:dbid]))
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:uuid => (the_uuid)}})
        end
        result
      end
      #
      def persistable?(the_object)
        result = true
        unless the_object.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
          if the_object.is_any?(::Hash, ::Array)
            the_object.search do |item, selector, container|
              if result
                if ::GxG::Database::Database::element_table_for_instance(item) == :unspecified
                  result = false
                  break
                end
              end
              nil
            end
          else
            if ::GxG::Database::Database::element_table_for_instance(the_object) == :unspecified
              result = false
            end
          end
        end
        result
      end
      #
      def iterative_persist(old_root=nil, credential=nil, options={})
        # New PersistedArray, or PersistedHash interface:
        # mount element: {:database => <database>, :uuid => <uuid>, :credential => <uuid>, :delegate => nil/<uuid>, :parent => nil/<an-object>}
        # create element: {:database => <database>, :credential => <uuid>, :delegate => nil/<uuid>, :parent => nil/<an-object>}
        # 
        result = nil
        begin
          # db open?
          # write permissions on db?
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You MUST provide a valid UUID as a credential."
          end
          unless old_root.is_any?(::Array, ::Hash)
            raise ArgumentError, "You MUST provide either an Array or a Hash."
          end
          unless self.persistable?(old_root)
            raise ArgumentError, "The object you are attempting to persist contains a non-persistable item."
          end
          if old_root.is_a?(::Array)
            original_partner = ::GxG::Database::PersistedArray.new({:database => self, :credential => credential}, options)
            original_partner.get_reservation()
            self.enforce_permission_policy({:action => :extend, :credential => credential, :source => original_partner, :destination => original_partner})
            #
          end
          if old_root.is_a?(::Hash)
            original_partner = ::GxG::Database::PersistedHash.new({:database => self, :credential => credential}, options)
            original_partner.get_reservation()
            self.enforce_permission_policy({:action => :extend, :credential => credential, :source => original_partner, :destination => original_partner})
          end
          if old_root.is_any?(::GxG::Database::PersistedArray, ::GxG::Database::PersistedHash)
            # TODO: support subsuming already persisted objects.
          end
          paring_data = [{:parent => nil, :parent_selector => nil, :object => old_root, :partner => original_partner}]
          children_of = Proc.new do |the_parent=nil|
            list = []
            paring_data.each do |node|
              if node[:parent].object_id == the_parent.object_id
                list << node
              end
            end
            list
          end
          #
          parent_of = Proc.new do |the_parent=nil|
            output = nil
            paring_data.each do |entry|
              if entry[:object].object_id == the_parent.object_id
                output = entry
              end
            end
            output
          end
          find_partner = Proc.new do |the_object|
            found_partner = nil
            paring_data.each do |the_record|
              if the_record.is_a?(::Hash)
                if the_record[:object].object_id == the_object.object_id
                  found_partner = the_record[:partner]
                  break
                end
              end
            end
            found_partner
          end
          # build paring data:
          delegate_permission = nil
          old_root.search do |the_value, the_selector, the_container|
            if the_value.is_a?(::Array)
              paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => ::GxG::Database::PersistedArray.new({:database => self, :credential => credential})}
            else
              if the_value.is_a?(::Hash)
                paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => ::GxG::Database::PersistedHash.new({:database => self, :credential => credential})}
              else
                paring_data << {:parent => the_container, :parent_selector => the_selector, :object => the_value, :partner => the_value}
              end
            end
          end
          # Assign objects to structure in order by parent / parent_selector
          link_db = [(paring_data[0])]
          while link_db.size > 0
            entry = link_db.shift
            if entry.is_a?(::Hash)
              if entry[:object].is_any?(::Array, ::Hash)
                # get children and assign
                children = children_of.call(entry[:object])
                children.each do |child|
                  entry[:partner][(child[:parent_selector])] = child[:partner]
                  if child[:partner].is_any?(::GxG::Database::PersistedArray, ::GxG::Database::PersistedHash)
                    link_db << child
                  end
                end
              end
            end
          end
          result = original_partner
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:object => old_root, :credential => credential}})
        end
        result
      end
      #
      def try_persist(the_object=nil, credential=nil, options={})
        result = nil
        if the_object.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
          result = the_object
        else
          begin
            unless ::GxG::valid_uuid?(credential)
              raise ArgumentError, "You must supply a credential (36 character limit) as a String or Symbol"
            end
            unless options.is_a?(::Hash)
              raise ArgumentError, "You must supply persisting options as a Hash"
            end
            table = ::GxG::Database::Database::element_table_for_instance(the_object)
            if table == :unspecified
              raise ArgumentError, "You provided an object that cannot be persisted."
            end
            if [:element_hash, :element_array].include?(table)
              result = self.iterative_persist(the_object, credential, options)
            else
              result = the_object
            end
          rescue Exception => the_error
            log_error({:error => the_error, :parameters => {:object => the_object, :credential => credential, :options => options}})
          end
        end
        result
      end
      #
      def retrieve_by_address(the_address={}, credential=nil, delegate=nil)
        result = nil
        begin
          unless ::GxG::valid_uuid?(credential)
            raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
          end
          if self.alive?
            if self.open?
              address = {}
              if the_address[:database]
                unless the_address[:database] == self
                  raise ArgumentError, "Database mismatch.  Call this method on database #{the_address[:database].inspect}"
                end
                address[:database] = the_address[:database]
              else
                address[:database] = self
              end
              unless ((the_address[:table]) and (the_address[:dbid].is_a?(::Integer)))
                raise ArgumentError, "Invalid database address: #{the_address.inspect}"
              end
              if the_address[:table].is_a?(::Integer)
                address[:table] = ::GxG::Database::Database::element_table_by_index(the_address[:table])
              else
                address[:table] = the_address[:table]
              end
              address[:dbid] = the_address[:dbid]
              unless self.element_in_trash?(address[:table], address[:dbid])
                if [:persisted_array, :persisted_hash].include?(address[:table])
                  the_permission = address[:database].effective_element_permission(address[:table], address[:dbid], credential)
                else
                  the_permission = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => true}
                end
                # Review ????
                # puts "Effective Permission: #{the_permission.inspect} for #{address[:table].inspect},#{address[:dbid].inspect}"
                if the_permission[:read] == true
                  case address[:table]
                  when :element_array
                    record = address[:database].connector()[(address[:table].to_s.to_sym)].select(:uuid).where({:dbid => (address[:dbid])}).first
                    if record
                      result = ::GxG::Database::PersistedArray.new({:database => (address[:database]), :uuid => (record[:uuid].to_sym), :credential => (credential), :delegate => (delegate)})
                    else
                      raise Exception, "Unable to retrieve PersistedArray"
                    end
                  when :element_hash
                    record = address[:database].connector()[:element_hash].select(:uuid, :format).where({:dbid => (address[:dbid])}).first
                    if record
                      result = ::GxG::Database::PersistedHash.new({:database => (address[:database]), :uuid => (record[:uuid].to_sym), :credential => (credential), :delegate => (delegate)})
                      if result
                        if record[:format].to_s.size > 0
                          result.set_format(record[:format].to_sym)
                        end
                      end
                    else
                      raise Exception, "Unable to retrieve PersistedHash"
                    end
                  else
                    raise Exception, "Invalid table specifier: #{address[:table].inspect}"
                  end
                else
                  # At this point the idea is that if you don't have permissions to read it, you never see it
                  # raise Exception, "You don't have permission to retrieve this element"
                end
                #
              end
              #
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:address => (the_address), :credential => (credential), :delegate => (delegate)}})
        end
        result
      end
      #
      def retrieve_by_uuid(uuid=nil, credential=nil, delegate=nil)
        result = nil
        begin
          if self.alive?
            if self.open?
              address = nil
              record = @connector[:element_hash].filter({:uuid => (uuid.to_s)}).first
              if record
                address = {:database => self, :table => :element_hash, :dbid => (record[:dbid])}
              else
                record = @connector[:element_array].filter({:uuid => (uuid.to_s)}).first
                if record
                  address = {:database => self, :table => :element_array, :dbid => (record[:dbid])}
                end
              end
              if address
                result = self.retrieve_by_address(address, credential, delegate)
              else
                # ### Review : Experimental Code - attempt to seemlessly integrate dbs of different roles into in-memory structures.
                already_checked = [(self)]
                ::GxG::DB[:roles].each_pair do |the_db_role, the_database|
                  unless already_checked.include?(the_database)
                    record = the_database.connector[:element_hash].filter({:uuid => (uuid.to_s)}).first
                    if record
                      address = {:database => the_database, :table => :element_hash, :dbid => (record[:dbid])}
                      result = the_database.retrieve_by_address(address, credential, delegate)
                      break
                    else
                      record = the_database.connector[:element_array].filter({:uuid => (uuid.to_s)}).first
                      if record
                        address = {:database => the_database, :table => :element_array, :dbid => (record[:dbid])}
                        result = the_database.retrieve_by_address(address, credential, delegate)
                        break
                      end
                    end
                    already_checked << the_database
                  end
                end
                # 
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:uuid => (uuid), :credential => (credential), :delegate => (delegate)}})
        end
        result
      end
      # Element Write-Lock Handling methods
      def reserve_element_locks(credential=nil, manifest=[], type=:read)
        result = nil
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(credential)
                raise ArgumentError, "You must supply a valid credential UUID to reserve locks"
              end
              unless manifest.is_a?(::Array)
                raise ArguementError, "You must supply an Array of tables and record ids to reserve for writing"
              end
              unless [:write, :read].include?(type)
                raise ArgumentError, "You must specify a type of reservation: either :write or :read are supported"
              end
              if manifest.size > 0
                reservation_uuid = ::GxG::uuid_generate()
                while @connector[:element_locks].filter({:reservation => (reservation_uuid.to_s)}).count > 0
                  reservation_uuid = ::GxG::uuid_generate()
                end
                if type == :write
                  if self.db_permissions()[:write]
                    # Write-lock must be unique to the elements
                    manifest.each do |entry|
                      if @connector[:element_locks].filter({:type => (type.to_s), :element_table => entry[:table].to_s, :elementid => entry[:dbid]}).count > 0
                        self.release_element_locks(reservation_uuid)
                        # raise Exception, "A reservation already exists for element #{entry[:table]}:#{entry[:dbid]}"
                        # Note - just silently fail and return Nil - no reservation for you.
                        break
                      else
                        @connector[:element_locks].insert({:type => (type.to_s), :reservation => reservation_uuid.to_s, :credential => credential.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                      end
                    end
                    # if write-reservation was made
                    if @connector[:element_locks].filter({:reservation => reservation_uuid.to_s}).count > 0
                      result = reservation_uuid.to_sym
                    end
                  end
                else
                  # Read-lock reservation - can share elements
                  if self.db_permissions()[:write]
                    manifest.each do |entry|
                      @connector[:element_locks].insert({:type => (type.to_s), :reservation => reservation_uuid.to_s, :credential => credential.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                      #
                    end
                  end
                  # Note - on a read-only db it will act as though it has a read-reservation since no deletions can be made.
                  result = reservation_uuid.to_sym
                end
              end
              #
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:credential => (credential), :manifest => (manifest), :type => (type)}})
        end
        result
      end
      #
      def release_element_locks(reservation_uuid=nil)
        result = false
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(reservation_uuid)
                raise ArgumentError, "You must supply a valid reservation UUID (as a String or Symbol) to release locks"
              end
              if self.db_permissions()[:write]
                @connector[:element_locks].filter({:reservation => reservation_uuid.to_s}).delete
              end
              # on read-only db, no reservation was made so mission accomplished
              result = true
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:reservation => (reservation_uuid)}})
        end
        result
      end
      #
      def reservation_add_element(reservation_uuid=nil, table=:unspecified, dbid=0)
        result = false
        #
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(reservation_uuid)
                raise ArgumentError, "You must supply a valid reservation UUID (as a String or Symbol) to add an element to the reserve locks"
              end
              record = @connector[:element_locks].select(:type, :reservation, :credential).where({:reservation => reservation_uuid.to_s}).first
              if record
                type = record[:type].to_sym
                credential = record[:credential].to_sym
                manifest = self.element_manifest(table, dbid, false)
                if type == :write
                  if self.db_permissions()[:write]
                    #
                    manifest.each do |entry|
                      if @connector[:element_locks].filter({:type => (type.to_s), :reservation => reservation_uuid.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]}).count == 0
                        @connector[:element_locks].insert({:type => (type.to_s), :reservation => reservation_uuid.to_s, :credential => credential.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                      end
                    end
                    result = true
                  end
                else
                  # read
                  if self.db_permissions()[:write]
                    #
                    manifest.each do |entry|
                      @connector[:element_locks].insert({:type => (type.to_s), :reservation => reservation_uuid.to_s, :credential => credential.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]})
                    end
                    result = true
                  end
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:reservation => (reservation_uuid)}})
        end
        #
        result
      end
      #
      def reservation_remove_element(reservation_uuid=nil, table=:unspecified, dbid=0)
        result = false
        #
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(reservation_uuid)
                raise ArgumentError, "You must supply a valid reservation UUID (as a String or Symbol) to remove element from reserve locks"
              end
              record = @connector[:element_locks].select(:reservation).where({:reservation => reservation_uuid.to_s}).first
              if record
                manifest = self.element_manifest(table, dbid, false)
                if self.db_permissions()[:write]
                  #
                  manifest.each do |entry|
                    if @connector[:element_locks].filter({:reservation => reservation_uuid.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]}).count > 0
                      @connector[:element_locks].filter({:reservation => reservation_uuid.to_s, :element_table => entry[:table].to_s, :elementid => entry[:dbid]}).delete
                    end
                  end
                  result = true
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Database not available (defunct)"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:reservation => (reservation_uuid)}})
        end
        #
        result
      end
      #
      def empty_trash()
        result = false
        begin
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                scrub_list = []
                @connector[:trash].filter({}).each do |entry|
                  the_table = entry[:element_table].to_sym
                  the_dbid = entry[:elementid]
                  if @connector[:element_locks].filter({:type => "write", :element_table => the_table.to_s, :elementid => the_dbid}).count == 0
                    # delete full manifest
                    manifest = self.element_manifest(the_table, the_dbid, true)
                    manifest.each do |item|
                      @connector[:permissions].filter({:element_table => (item[:table].to_s), :elementid => (item[:dbid])}).delete
                      @connector[(item[:table])].filter({:dbid => item[:dbid]}).delete
                    end
                    scrub_list << entry[:dbid]
                  end
                end
                scrub_list.each do |entry|
                  @connector[:trash].filter({:dbid => entry}).delete
                end
                if @connector[:trash].filter({}).count == 0
                  result = true
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error})
        end
        result
      end
      #
      def element_in_trash?(table=:unspecified, dbid=0)
        result = false
        begin
          if self.alive?
            if self.open?
              if @connector[:trash].filter({:element_table => table.to_s, :elementid => dbid}).count > 0
                result = true
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid)}})
        end
        result
      end
      #
      def element_recover(table=:unspecified, dbid=0)
        # recover an element from the trash
        result = false
        begin
          if self.alive?
            if self.open?
              if self.db_permissions()[:write]
                unless [:element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime, :element_text, :element_binary, :element_array, :element_hash].include?(table)
                  raise ArgumentError, "Invalid table specified"
                end
                unless dbid > 0
                  raise ArgumentError, "dbid must be greater than zero"
                end
                if self.element_in_trash?(table, dbid)
                  scrub_list = []
                  manifest = self.element_manifest(table, dbid)
                  manifest.each do |entry|
                    if @connector[:trash].filter({:element_table => (entry[:table].to_s), :elementid => (entry[:dbid])}).count > 0
                      record = @connector[:trash].select(:dbid).where({:element_table => (entry[:table].to_s), :elementid => (entry[:dbid])}).first
                      if record
                        scrub_list << record[:dbid]
                      end
                    end
                  end
                  scrub_list.each do |entry|
                    @connector[:trash].filter({:dbid => entry}).delete
                  end
                  result = true
                else
                  # it was never in the trash, so mission accomplished
                  result = true
                end
              end
            end
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:table => (table), :dbid => (dbid)}})
        end
        result
      end
      # ### Format handing methods
      def format_template(type=:structure)
        result = nil
        begin
          if self.alive?
            if self.open?
              unless type.is_any?(::String, ::Symbol)
                raise ArgumentError, "You must supply a type as a String or Symbol:  :structure or :binary"
              end
              the_uuid = ::GxG::uuid_generate()
              while (@connector[:formats].filter({:uuid => (the_uuid)}).count > 0 or @connector[:element_text].filter({:uuid => (the_uuid)}).count > 0)
                the_uuid = ::GxG::uuid_generate()
              end
              result = {:uuid => (the_uuid.to_sym), :type => (type.to_s), :ufs => "unspecified", :title => "", :version => BigDecimal(0.0), :mime_types => [], :content => nil}
              case type
              when :structure
                result[:content] = {}
              when :binary
                result[:content] = {:sample_size => 0, :recognition => "", :import => "", :export => ""}
              else
                raise Exception, "Invalid format type specified: #{type.inspect}.  Use :structure or :binary"
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          result = nil
          log_error({:error => the_error, :parameters => {:type => (type)}})
        end
        result
      end
      #
      def format_list(search_options={})
        result = []
        begin
          if self.alive?
            if self.open?
              unless search_options.is_a?(::Hash)
                raise ArgumentError, "You must specify search options as a Hash"
              end
              the_filter = {}
              if search_options[:uuid]
                the_filter[:uuid] = search_options[:uuid].to_s
              end
              if search_options[:type]
                the_filter[:type] = search_options[:type].to_s
              end
              if search_options[:ufs]
                the_filter[:ufs] = search_options[:ufs].to_s[0..4096]
              end
              if search_options[:title]
                the_filter[:title] = search_options[:title].to_s[0..256]
              end
              if search_options[:version].is_a?(::Numeric)
                the_filter[:version] = ::BigDecimal.new(search_options[:version].to_s)
              end
              mime_type = search_options[:mime_type].to_s
              if mime_type.size > 0
                @connector[:formats].filter(the_filter).where(::Sequel.like(:mime_types, ("%" + mime_type + "%"))).order(::Sequel[:version].desc).each do |entry|
                  result << {:uuid => entry[:uuid].to_sym, :type => entry[:type].to_sym, :ufs => entry[:ufs].to_sym, :title => entry[:title], :version => entry[:version]}
                end
              else
                @connector[:formats].filter(the_filter).order(::Sequel[:version].desc).each do |entry|
                  result << {:uuid => entry[:uuid].to_sym, :type => entry[:type].to_sym, :ufs => entry[:ufs].to_sym, :title => entry[:title], :version => entry[:version]}
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:search_options => (search_options)}})
        end
        result
      end
      #
      def format_load(search_options={})
        result = nil
        begin
          if self.alive?()
            if self.open?
              format_stub = self.format_list(search_options).first
              if format_stub
                format_record = @connector[:formats].filter({:uuid => (format_stub[:uuid].to_s)}).first
                if format_record
                  content = ""
                  @connector[:text_page].filter({:parent_uuid => (format_stub[:uuid].to_s)}).order(:ordinal).each do |entry|
                    content << entry[:content]
                  end
                  format_record.delete(:dbid)
                  format_record[:ufs] = format_stub[:ufs]
                  format_record[:type] = format_stub[:type]
                  if content.size > 0
                    if content.base64?
                      content = content.decode64
                    end
                    if content.json?
                      content = ::JSON::parse(content.to_s, {:symbolize_names => true})
                    end
                    if content[:type]
                      content = ::Hash.gxg_import(content)
                    end
                    format_record[:content] = content
                  else
                    format_record[:content] = nil
                  end
                  #
                  if format_record[:mime_types].size > 0
                    if format_record[:mime_types].include?(",")
                      format_record[:mime_types] = format_record[:mime_types].split(",")
                    else
                      format_record[:mime_types] = [(format_record[:mime_types])]
                    end
                  end
                  #
                  result = format_record
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:search_options => (search_options)}})
        end
        result
      end
      #
      def new_structure_from_format(credential=nil, search_options={})
        result = nil
        begin
          if self.alive?()
            if self.open?
              unless ::GxG::valid_uuid?(credential)
                raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
              end
              format = self.format_load(search_options)
              if format
                # TODO: add support for :binary formats.
                unless format[:type] == :structure
                  raise Exception, "Only formats of type :structure are supported"
                end
                result = self.try_persist(format[:content], credential)
                if result.is_a?(::GxG::Database::PersistedHash)
                  result.set_format(format[:uuid].to_sym)
                  @connector[:element_hash].filter({:uuid => result.uuid.to_s}).update({:format => format[:uuid].to_s})
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:search_options => (search_options)}})
        end
        result
      end
      #
      def format_create(format_record=nil)
        result = false
        begin
          if self.alive?()
            if self.open?
              unless self.db_permissions()[:write]
                raise Exception, "Unable to write to database"
              end
              if format_record.is_a?(::Hash)
                unless ::GxG::valid_uuid?(format_record[:uuid])
                  raise Exception, "Invalid UUID passed for the format"
                end
                unless format_record[:type].is_any?([::String, ::Symbol])
                  raise Exception, "You must pass the format_record[:type] as a String or Symbol"
                end
                unless format_record[:ufs].is_any?([::String, ::Symbol])
                  raise Exception, "You must pass the format_record[:ufs] as a String or Symbol"
                end
                unless format_record[:title].is_a?(::String)
                  raise Exception, "You must pass the format_record[:title] as a String"
                end
                unless format_record[:version].is_a?(::Numeric)
                  raise Exception, "You must pass the format_record[:version] as a Numeric"
                end
                unless format_record[:mime_types].is_any?(::String, ::Array)
                  raise Exception, "You must pass the format_record[:mime_types] as a String"
                end
                unless format_record[:content].is_a?(::Hash)
                  raise Exception, "You must pass the format_record[:content] as a Hash"
                end
                unless self.persistable?(format_record[:content])
                  raise Exception, "You must pass the format_record[:content] as a Hash of persistable elements"
                end
                if (@connector[:settings].filter({:uuid => format_record[:uuid].to_s}).count == 0 and @connector[:formats].filter({:uuid => format_record[:uuid].to_s}).count == 0 and @connector[:element_text].filter({:uuid => format_record[:uuid].to_s}).count == 0)
                  new_record = {:uuid => (format_record[:uuid].to_s)}
                  new_record[:type] = format_record[:type].to_s
                  new_record[:ufs] = format_record[:ufs].to_s
                  new_record[:title] = format_record[:title].to_s[0..256]
                  new_record[:version] = ::BigDecimal.new(format_record[:version].to_s)
                  if format_record[:mime_types].is_a?(::Array)
                    the_mimes = format_record[:mime_types].join(",").to_s[0..4096]
                  else
                    the_mimes = format_record[:mime_types].to_s[0..4096]
                  end
                  new_record[:mime_types] = the_mimes
                  content = format_record[:content].gxg_export.to_json.encode64
                  new_dbid = @connector[:formats].insert(new_record)
                  if content.size > 0
                    ::GxG::apportioned_ranges(content.size, 4096).each_with_index do |portion, ordinal|
                      @connector[:text_page].insert({:parent_uuid => (new_record[:uuid].to_s), :ordinal => (ordinal), :length => (content[(portion)].size), :content => (content[(portion)])})
                    end
                  end
                  if new_dbid
                    result = true
                  end
                  #
                  if result == true && ::GxG::DB[:roles][:formats] == self
                    already = [(self)]
                    GxG::DB[:roles].values.each do |the_db|
                        unless already.include?(the_db)
                            the_db.format_create(format_record)
                            already << the_db
                        end
                    end
                  end
                  #
                else
                  raise Exception, "That format UUID is already in use, please generate another"
                end
                #
              else
                raise ArgumentError, "You must supply a valid format record as a Hash"
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:format_record => (format_record)}})
        end
        result
      end
      #
      def format_update(format_record=nil)
        format_record = format_record.clone
        result = false
        begin
          if self.alive?()
            if self.open?
              unless self.db_permissions()[:write]
                raise Exception, "Unable to write to database"
              end
              if format_record.is_a?(::Hash)
                unless ::GxG::valid_uuid?(format_record[:uuid])
                  raise Exception, "Invalid UUID passed for the format"
                end
                record = @connector[:formats].filter({:uuid => format_record[:uuid].to_s}).first
                if record
                  format_update = {}
                  record.keys.each do |the_key|
                    if [:type, :ufs, :title, :version, :mime_types].include?(the_key)
                      case the_key
                      when :type
                        unless format_record[:type].is_any?(::String, ::Symbol)
                          raise Exception, "You must pass the format_record[:type] as a String or Symbol"
                        end
                      when :ufs
                        unless format_record[:ufs].is_any?(::String, ::Symbol)
                          raise Exception, "You must pass the format_record[:ufs] as a String or Symbol"
                        end
                      when :title
                        unless format_record[:title].is_a?(::String)
                          raise Exception, "You must pass the format_record[:title] as a String"
                        end
                      when :version
                        unless format_record[:version].is_a?(::Numeric)
                          raise Exception, "You must pass the format_record[:version] as a Numeric"
                        end
                      when :mime_types
                        unless format_record[:mime_types].is_any?(::String, ::Array)
                          raise Exception, "You must pass the format_record[:mime_types] as a String"
                        end
                      end
                      #
                      if the_key == :mime_types
                        if format_record[:mime_types].is_a?(::Array)
                          the_mimes = format_record[:mime_types].join(",").to_s[0..4096]
                        else
                          the_mimes = format_record[:mime_types].to_s[0..4096]
                        end
                        format_record[:mime_types] = the_mimes
                      end
                      #
                      if format_record[(the_key)] != record[(the_key)]
                        format_update[(the_key)] = format_record[(the_key)]
                      end
                    end
                  end                  
                  if format_update.keys.size > 0
                    # FIXME: :type and :ufs are being passed as a Symbols, but DB requires them to be a strings:
                    if format_update[:type].is_a?(::Symbol)
                      format_update[:type] = format_update[:type].to_s
                    end
                    if format_update[:ufs].is_a?(::Symbol)
                      format_update[:ufs] = format_update[:ufs].to_s
                    end
                    @connector[:formats].filter({:uuid => format_record[:uuid].to_s}).update(format_update)
                  end
                  if format_record[:content].is_a?(::Hash)
                    unless self.persistable?(format_record[:content])
                      raise Exception, "You must pass the format_record[:content] as a Hash of persistable elements"
                    end
                    old_segments = []
                    content = format_record[:content].gxg_export.to_json.encode64
                    @connector[:text_page].select(:dbid).where({:parent_uuid => format_record[:uuid].to_s}).order(:ordinal).each do |entry|
                      old_segments << entry[:dbid]
                    end
                    if content.size == 0
                      if old_segments.size > 0
                        @connector[:text_page].filter({:parent_uuid => format_record[:uuid].to_s}).delete
                      end
                    else
                      new_segments = ::GxG::apportioned_ranges(content.size, 4096)
                      if old_segments.size > new_segments.size
                        the_count = old_segments.size
                      else
                        the_count = new_segments.size
                      end
                      manifest = []
                      (0..(the_count - 1)).each do |the_ordinal|
                        if new_segments[(the_ordinal)] and old_segments[(the_ordinal)]
                          #overwrite with new segment range
                          manifest << {:operation => :overwrite, :dbid => (old_segments[(the_ordinal)]), :ordinal => (the_ordinal), :portion => (new_segments[(the_ordinal)])}
                        else
                          if new_segments[(the_ordinal)]
                            # create new segment at this ordinal
                            manifest << {:operation => :create, :ordinal => (the_ordinal), :portion => (new_segments[(the_ordinal)])}
                          else
                            # delete old segment
                            manifest << {:operation => :delete, :dbid => (old_segments[(the_ordinal)])}
                          end
                        end
                      end
                      manifest.each do |action|
                        case action[:operation]
                        when :overwrite
                          @connector[:text_page].filter({:dbid => (action[:dbid])}).update({:ordinal => (action[:ordinal]), :length => (content[(action[:portion])].size), :content => (content[(action[:portion])])})
                        when :create
                          @connector[:text_page].insert({:parent_uuid => (record[:uuid]), :ordinal => (action[:ordinal]), :length => (content[(action[:portion])].size), :content => (content[(action[:portion])])})
                        when :delete
                          @connector[:text_page].filter({:dbid => (action[:dbid])}).delete
                        end
                      end
                      @connector[:formats].filter({:uuid => format_record[:uuid].to_s}).update({:version => (::BigDecimal.new(format_record[:version].to_s) + 0.0001)})
                      #
                    end
                  end
                  #
                  result = true
                  #
                  if result == true && ::GxG::DB[:roles][:formats] == self
                    already = [(self)]
                    GxG::DB[:roles].values.each do |the_db|
                        unless already.include?(the_db)
                            the_db.format_update(format_record)
                            already << the_db
                        end
                    end
                  end
                  #
                else
                  result = self.format_create(format_record)
                end
              else
                raise ArgumentError, "You must supply a valid format record as a Hash"
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:format_record => (format_record)}})
        end
        result
      end
      #
      def format_destroy(search_options={})
        result = false
        begin
          if self.alive?()
            if self.open?
              unless self.db_permissions()[:write]
                raise Exception, "Unable to write to database"
              end
              format_stub = self.format_list(search_options).first
              if format_stub
                @connector[:formats].filter({:uuid => (format_stub[:uuid].to_s)}).delete
                if @connector[:text_page].filter({:parent_uuid => (format_stub[:uuid].to_s)}).count > 0
                  @connector[:text_page].filter({:parent_uuid => (format_stub[:uuid].to_s)}).delete
                end
                result = true
                #
                if result == true && ::GxG::DB[:roles][:formats] == self
                  already = [(self)]
                  GxG::DB[:roles].values.each do |the_db|
                      unless already.include?(the_db)
                          the_db.format_destroy(search_options)
                          already << the_db
                      end
                  end
                end
                #
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:search_options => (search_options)}})
        end
        result
      end
      # Settings methods
      def setting_keys()
        result = []
        begin
          if self.alive?()
            if self.open?()
              @connector[:settings].all.each do |the_entry|
                result << the_entry[:title].to_sym
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:setting_key => setting_key}})
        end
        result
      end
      #
      def [](setting_key=nil)
        result = nil
        begin
          if self.alive?()
            if self.open?()
              record = @connector[:settings].filter({:title => setting_key.to_s}).first
              if record
                content = ""
                @connector[:text_page].select(:content).where({:parent_uuid => record[:uuid].to_s}).order(:ordinal).each do |entry|
                  content << entry[:content]
                end
                if content.size > 0
                  result = content.unserialize()
                end
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:setting_key => setting_key}})
        end
        result
      end
      #
      def []=(setting_key=nil, object=nil)
        result = object
        begin
          if self.alive?()
            if self.open?()
              unless self.db_permissions()[:write]
                raise Exception, "Unable to write to database"
              end
              unless setting_key.is_a?(::Symbol)
                raise ArgumentError, "You must supply a setting key as a Symbol"
              end
              unless setting_key.to_s.size > 0
                raise ArgumentError, "You must supply a setting key whose length is greater than zero"
              end
              record = @connector[:settings].filter({:title => setting_key.to_s}).first
              unless record
                new_uuid = ::GxG::uuid_generate().to_s
                while (@connector[:settings].filter({:uuid => (new_uuid)}).count > 0 or @connector[:formats].filter({:uuid => (new_uuid)}).count > 0 or @connector[:element_text].filter({:uuid => (new_uuid)}).count > 0)
                  new_uuid = ::GxG::uuid_generate().to_s
                end
                @connector[:settings].insert({:title => setting_key.to_s, :uuid => new_uuid.to_s})
                record = @connector[:settings].filter({:uuid => (new_uuid)}).first
              end
              if record
                @connector[:settings].filter({:dbid => (record[:dbid])}).update({:version => (record[:version] + 0.0001)})
                content = object.serialize()
                old_segments = []
                @connector[:text_page].select(:dbid).where({:parent_uuid => record[:uuid].to_s}).order(:ordinal).each do |entry|
                  old_segments << entry[:dbid]
                end
                if content.size == 0
                  if old_segments.size > 0
                    @connector[:text_page].filter({:parent_uuid => record[:uuid].to_s}).delete
                  end
                else
                  new_segments = ::GxG::apportioned_ranges(content.size, 4096)
                  if old_segments.size > new_segments.size
                    the_count = old_segments.size
                  else
                    the_count = new_segments.size
                  end
                  manifest = []
                  (0..(the_count - 1)).each do |the_ordinal|
                    if new_segments[(the_ordinal)] and old_segments[(the_ordinal)]
                      #overwrite with new segment range
                      manifest << {:operation => :overwrite, :dbid => (old_segments[(the_ordinal)]), :ordinal => (the_ordinal), :portion => (new_segments[(the_ordinal)])}
                    else
                      if new_segments[(the_ordinal)]
                        # create new segment at this ordinal
                        manifest << {:operation => :create, :ordinal => (the_ordinal), :portion => (new_segments[(the_ordinal)])}
                      else
                        # delete old segment
                        manifest << {:operation => :delete, :dbid => (old_segments[(the_ordinal)])}
                      end
                    end
                  end
                  manifest.each do |action|
                    case action[:operation]
                    when :overwrite
                      @connector[:text_page].filter({:dbid => (action[:dbid])}).update({:ordinal => (action[:ordinal]), :length => (content[(action[:portion])].size), :content => (content[(action[:portion])])})
                    when :create
                      @connector[:text_page].insert({:parent_uuid => (record[:uuid]), :ordinal => (action[:ordinal]), :length => (content[(action[:portion])].size), :content => (content[(action[:portion])])})
                    when :delete
                      @connector[:text_page].filter({:dbid => (action[:dbid])}).delete
                    end
                  end
                  #
                end
              else
                raise Exception, "Internal Error - could not retrieve setting record: #{setting_key.inspect}"
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:setting => setting_key, :object => object}})
        end
        result
      end
      #
      # Permission policy support:
      def permission_policy()
        result = nil
        begin
          if self.alive?()
            if self.open?()
              if @authority
                result = @authority.permission_policy()
              else
                result = @permission_policy
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {}})
        end
        result
      end
      #
      def permission_policy_load()
        result = false
        begin
          if self.alive?()
            if self.open?()
              if @authority
                result = @authority.permission_policy_load()
              else
                @permission_policy = (self[:permission_policy] || [])
                result = true
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {}})
        end
        result
      end
      #
      def permission_policy_save()
        result = false
        begin
          if self.alive?()
            if self.open?()
              if @authority
                result = @authority.permission_policy_save()
              else
                self[:permission_policy] = (@permission_policy || [])
                result = true
              end
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {}})
        end
        result
      end
      #
      def enforce_permission_policy(event={})
        # Event format: enforce_permission_policy({:action => :extend, :credential => nil, :source => nil, :destination => nil})
        # Rule format: {:event => :create, :credential => :any, :action => {:extend_permissions => nil}}
        the_policy = self.permission_policy()
        result = false
        begin
          if self.alive?()
            if self.open?()
              actions = []
              the_policy.each do |rule|
                if event[:action] == rule[:event]
                  if rule[:credential] == event[:credential] || rule[:credential] == :any
                    actions << rule[:action]
                  end
                end
              end
              actions.each do |action|
                case action.keys[0]
                when :extend_permissions
                  if action[:use_permission].is_a?(::Hash)
                    use_permission = action[:use_permission]
                  else
                    use_permission = nil
                  end
                  credential = event[:credential]
                  unless ::GxG::valid_uuid?(credential)
                    raise ArgumentError, "You MUST provide a valid UUID as :credential."
                  end
                  new_credential = action[:extend_permissions]
                  source = event[:source]
                  unless source.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
                    raise ArgumentError, "You MUST provide a persisted object as :source."
                  end
                  unless source.db_address
                    raise Exception, "You provided a Deactivated object as :source."
                  end
                  destination = event[:destination]
                  unless destination.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
                    raise ArgumentError, "You MUST provide a persisted object as :source."
                  end
                  unless destination.db_address
                    raise Exception, "You provided a Deactivated object as :destination."
                  end
                  #
                  permissions = self.element_permissions(source.db_address()[:table],source.db_address()[:dbid])
                  permission_db = []
                  if [:persisted_array, :persisted_hash].include?(destination.db_address()[:table])
                    search_db = [{:table => destination.db_address()[:table], :dbid => destination.db_address()[:dbid]}]
                    permission_db << {:table => destination.db_address()[:table], :dbid => destination.db_address()[:dbid]}
                    while search_db.size > 0 do
                      entry = search_db.shift
                      self.element_manifest(entry[:table],entry[:dbid],false).each do |item|
                        if [:persisted_array, :persisted_hash].include?(item[:table])
                          search_db << item
                          permission_db << item
                        end
                      end
                    end
                    permission_db.each do |the_reference|
                      permissions.each do |record|
                        self.assign_element_permission(the_reference[:table],the_reference[:dbid], credential, record[:permissions])
                        if use_permission
                          self.assign_element_permission(the_reference[:table],the_reference[:dbid], new_credential, use_permission)
                        else
                          self.assign_element_permission(the_reference[:table],the_reference[:dbid], new_credential, record[:permissions])
                        end
                      end
                    end
                    # destination.search do |the_value, the_selector, the_container|
                    #   if [:persisted_array, :persisted_hash].include?(the_value.db_address()[:table])
                    #     permission_db << {:table => the_value.db_address()[:table], :dbid => the_value.db_address()[:dbid]}
                    #   end
                    # end
                    #
                  end
                  # permission_db << {:table => destination.db_address()[:table], :dbid => destination.db_address()[:dbid]}
                  # if destination.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::PersistedArray)
                  #   destination.search do |the_value, the_selector, the_container|
                  #     permission_db << {:table => the_value.db_address()[:table], :dbid => the_value.db_address()[:dbid]}
                  #   end
                  # end
                  # permission_db.each do |item|
                  #   self.element_manifest(item[:table],item[:dbid],false).each do |entry|
                  #     permissions.each do |record|
                  #       self.assign_element_permission(entry[:table],entry[:dbid], credential, record[:permissions])
                  #       if use_permission
                  #         self.assign_element_permission(entry[:table],entry[:dbid], new_credential, use_permission)
                  #       else
                  #         self.assign_element_permission(entry[:table],entry[:dbid], new_credential, record[:permissions])
                  #       end
                  #     end
                  #   end
                  # end
                  #
                end
              end
              result = true
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:event => event}})
        end
        result
      end
      # ### Import methods (deprecated in favor of sychronize_records)
      def import(credential=nil, the_record=nil)
        #
        result = nil
        if self.alive?
          if self.open?
            if self.db_permissions()[:write]
              cleanup_manifest = []
              begin
                unless ::GxG::valid_uuid?(credential)
                  raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
                end
                if the_record.is_a?(::Hash)
                  case the_record[:type]
                  when :element_boolean, :element_integer, :element_float, :element_bigdecimal, :element_datetime
                    new_dbid = @connector[(the_record[:type])].insert({:version => (the_record[:version]), :content => (the_record[:content])})
                    self.assign_element_permission((the_record[:type]), (new_dbid), credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                    result = {:table => (the_record[:table]), :dbid => (new_dbid)}
                  when :element_text
                    the_uuid = ::GxG::uuid_generate()
                    while (@connector[:element_text].filter({:uuid => the_uuid}).count > 0)
                      the_uuid = ::GxG::uuid_generate()
                    end
                    new_dbid = @connector[:element_text].insert({:uuid => (the_uuid), :version => (the_record[:version]), :length => (the_record[:content].size)})
                    cleanup_manifest << {:table => :element_text, :dbid => (new_dbid)}
                    ::GxG::apportioned_ranges(the_record[:content].size, 4096).each_with_index do |the_range,the_ordinal|  
                      @connector[:text_page].insert({:parent_uuid => (the_uuid), :ordinal => (the_ordinal), :length => (the_record[:content][(the_range)].size), :content => (the_record[:content][(the_range)])})
                    end
                    self.assign_element_permission((the_record[:type]), (new_dbid), credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                    result = {:table => :element_text, :dbid => (new_dbid)}
                  when :element_binary
                    the_uuid = ::GxG::uuid_generate()
                    while (@connector[:element_binary].filter({:uuid => the_uuid}).count > 0)
                      the_uuid = ::GxG::uuid_generate()
                    end
                    new_dbid = @connector[:element_binary].insert({:uuid => (the_uuid), :version => (the_record[:version]), :length => (the_record[:content].size)})
                    cleanup_manifest << {:table => :element_binary, :dbid => (new_dbid)}
                    ::GxG::apportioned_ranges(the_record[:content].size, 65536).each_with_index do |the_range,the_ordinal|  
                      @connector[:binary_page].insert({:parent_uuid => (the_uuid), :ordinal => (the_ordinal), :length => (the_record[:content].data()[(the_range)].size), :content => (the_record[:content].data()[(the_range)])})
                    end
                    self.assign_element_permission((the_record[:type]), (new_dbid), credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                    result = {:table => :element_binary, :dbid => (new_dbid)}
                  when :element_array
                    # {:type => :element_array, :uuid => @uuid, :title => @title, :version => @version, :content => []}
                    existing = @connector[(the_record[:type])].select(:dbid, :version).where({:uuid => the_record[:uuid].to_s}).first
                    if existing
                      if the_record[:version] > existing[:version]
                        unless self.element_destroy(credential, :element_array, existing[:dbid])
                          raise Exception, "Error replacing array element - Aborting"
                        end
                        existing = nil
                      else
                        log_warn("Import record is older than existing one - Skipping")
                        new_dbid = existing[:dbid]
                      end
                    end
                    unless existing
                      new_dbid = @connector[(the_record[:type])].insert({:uuid => (the_record[:uuid].to_s), :title => (the_record[:title]), :version => (the_record[:version])})
                      cleanup_manifest << {:table => :element_array, :dbid => (new_dbid)}
                      self.assign_element_permission(:element_array, (new_dbid), credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                      the_record[:content].each_with_index do |element, indexer|
                        new_address = self.import(credential, (element))
                        if new_address
                          cleanup_manifest << new_address
                          @connector[:array_links].insert({:parent_uuid => (the_record[:uuid].to_s), :ordinal => (indexer), :element => (::GxG::Database::Database::element_table_index(new_address[:table])), :elementid => new_address[:dbid]})
                        else
                          raise Exception, "Error processing the import record - Aborting"
                        end
                      end
                    end
                    result = {:table => :element_array, :dbid => (new_dbid)}
                  when :element_hash
                    # {:type => :element_hash, :uuid => @uuid, :title => @title, :version => @version, :format => @format, :content => {}}
                    existing = @connector[(the_record[:type])].select(:dbid, :version).where({:uuid => the_record[:uuid].to_s}).first
                    if existing
                      if the_record[:version] > existing[:version]
                        unless self.element_destroy(credential, :element_hash, existing[:dbid])
                          raise Exception, "Error replacing hash element - Aborting"
                        end
                        existing = nil
                      else
                        log_warn("Import record is older than existing one - Skipping")
                        new_dbid = existing[:dbid]
                      end
                    end
                    unless existing
                      new_dbid = @connector[(the_record[:type])].insert({:uuid => (the_record[:uuid].to_s), :title => (the_record[:title]), :version => (the_record[:version]), :format => (the_record[:format].to_s)})
                      cleanup_manifest << {:table => :element_hash, :dbid => (new_dbid)}
                      self.assign_element_permission(:element_hash, (new_dbid), credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                      the_record[:content].keys.each_with_index do |the_key, indexer|
                        new_address = self.import(credential, (the_record[:content][(the_key)]))
                        if new_address
                          cleanup_manifest << new_address
                          @connector[:hash_links].insert({:parent_uuid => (the_record[:uuid].to_s), :property => (the_key.to_s), :ordinal => (indexer), :element => (::GxG::Database::Database::element_table_index(new_address[:table])), :elementid => new_address[:dbid]})
                        else
                          raise Exception, "Error processing the import record - Aborting"
                        end
                      end
                    end
                    result = {:table => :element_hash, :dbid => (new_dbid)}
                  else
                    raise ArgumentError, "Invalid table specified"
                  end
                else
                  raise ArgumentError, "You must supply an import record as a Hash"
                end
              rescue Exception => the_error
                # clean up
                cleanup_manifest.each do |entry|
                  self.element_destroy(credential, entry[:table], entry[:dbid])
                end
                log_error({:error => the_error, :parameters => {:the_record => (the_record)}})
              end
            else
              log_warn("Cannot import records into a read-only Database - Aborting")
            end
          end
        end
        result
      end
      # ### Search function method
      def uuid_list(credential=nil, criteria={})
        # will return an array of all structures the credential has (at least) read access to
        result = []
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(credential)
                raise ArgumentError, "You must supply a valid credential UUID (as a String or Symbol)"
              end
              unless criteria.is_a?(::Hash)
                raise ArgumentError, "You must supply a search criteria as a Hash"
              end
              hash_criteria = {}
              array_criteria = {}
              # Limit, Offset, and Page selection
              if criteria[:limit].is_a?(::Integer)
                limit = criteria[:limit]
              else
                limit = nil
              end
              if criteria[:offset].is_a?(::Integer)
                offset = criteria[:offset]
              else
                offset = 0
              end
              if criteria[:page].is_a?(::Integer)
                page = criteria[:page]
                unless limit
                  limit = 100
                end
                offset = ((page * limit) - 1)
              else
                page = nil
              end
              # UUID, Title, and Format searches
              if ::GxG::valid_uuid?(criteria[:uuid])
                hash_criteria[:uuid] = criteria[:uuid].to_s
                array_criteria[:uuid] = criteria[:uuid].to_s
              end
              if criteria[:title].is_a?(::String)
                hash_criteria[:title] = criteria[:title].to_s[0..256]
                array_criteria[:title] = criteria[:title].to_s[0..256]
              end
              if criteria[:format].is_any?([::String, ::Symbol])
                if ::GxG::valid_uuid?(criteria[:format])
                  format_list = self.format_list({:uuid => criteria[:format].to_sym})
                  unless format_list.size > 0
                    raise ArgumentError, "Format not found: #{criteria[:format].inspect}"
                  end
                  hash_criteria[:format] = criteria[:format].to_s
                end
              end
              if criteria[:ufs].is_any?(::String, ::Symbol)
                if criteria[:ufs_version].is_a?(::Numeric)
                  format_list = self.format_list({:ufs => criteria[:ufs].to_sym, :version => ::BigDecimal.new(criteria[:ufs_version].to_s)})
                else
                  format_list = self.format_list({:ufs => criteria[:ufs].to_sym})
                end
                unless format_list.size > 0
                  if criteria[:ufs_version].is_a?(::Float)
                    raise ArgumentError, "Format not found: #{criteria[:ufs].inspect}, Version: #{criteria[:ufs_version].inspect}"
                  else
                    raise ArgumentError, "Format not found: #{criteria[:ufs].inspect}"
                  end
                end
                hash_criteria[:format] = format_list[0][:uuid].to_s
              end
              # Output column selection: (very very basic at first)
              selectables = [:uuid, :title, :version]
              selected = []
              if criteria[:select].is_any?(::Symbol, ::Array)
                if criteria[:select].is_a?(::Array)
                  criteria[:select].each do |the_column_symbol|
                    if selectables.include?(the_column_symbol)
                      selected << the_column_symbol
                    end
                  end
                else
                  if selectables.include?(criteria[:select])
                    selected << criteria[:select]
                  end
                end
              end
              if selected.size == 0
                selected << :uuid
              end
              #
              reduce_to_datetime = Proc.new do |the_value|
                the_result = nil
                db_content = nil
                if the_value.is_a?(::String)
                  if the_value.include?("between")
                    the_times = the_value.split("between")[1].split("and")
                    the_times[0] = ::Chronic.parse(the_times[0])
                    the_times[1] = ::Chronic.parse(the_times[1])
                    if the_times[0].is_a?(::Time) && the_times[1].is_a?(::Time)
                      db_content = ((the_times[0].to_datetime)..(the_times[1].to_datetime))
                    else
                      raise Exception, "Unable to understand your time specification text: #{the_value.inspect}"
                    end
                  else
                    if the_value.valid_time? || the_value.valid_date? || the_value.valid_datetime_nolocale? || the_value.valid_datetime?
                      db_content = ::DateTime::parse(the_value)
                    else
                      the_times = ::Chronic.parse(the_value)
                      if the_times.is_a?(::Time)
                        db_content = the_times.to_datetime
                      else
                        raise Exception, "Unable to understand your time specification text: #{the_value.inspect}"
                      end
                    end
                  end
                end
                if the_value.is_a?(::Range)
                  the_times = [(the_value.first), (the_value.last)]
                  if the_times[0].is_a?(::Time)
                    the_times[0] = the_times[0].to_datetime
                  end
                  if the_times[0].is_a?(::Date)
                    the_times[0] = ::DateTime::parse(the_times[0].to_s)
                  end
                  if the_times[1].is_a?(::Time)
                    the_times[1] = the_times[1].to_datetime
                  end
                  if the_times[1].is_a?(::Date)
                    the_times[1] = ::DateTime::parse(the_times[1].to_s)
                  end
                  the_times = ((the_times[0])..(the_times[1]))
                  if the_times.first.is_a?(::DateTime) && the_value.last.is_a?(::DateTime)
                    db_content = the_times
                  else
                    raise Exception, "Invalid Range of dates, use DateTime objects in the Range: #{the_value.inspect}"
                  end
                end
                if the_value.is_any?(::Time, ::Date)
                  db_content = ::DateTime::parse(the_value.to_s)
                end
                if the_value.is_a?(::DateTime)
                  db_content = the_value
                end
                if db_content
                  result = db_content
                else
                  raise Exception, "Unable to reduce to a DateTime with this input: #{the_value.inspect}"
                end
                the_result
              end
              #
              db_content_value = Proc.new do |the_value|
                the_result = nil
                the_table = ::GxG::Database::Database::element_table_for_instance(the_value)
                if the_table == :unspecified
                  raise Exception, "Invalid value passed as persistable: #{the_value.inspect}"
                else
                  db_content = nil
                  case the_table
                  when :element_boolean
                    if the_value.is_a?(::TrueClass)
                      db_content = 1
                    else
                      if the_value.is_a?(::FalseClass)
                        db_content = 0
                      else
                        db_content = -1
                      end
                    end
                  when :element_binary
                    db_content = ""
                    the_value.each do |the_byte|
                      db_content << the_byte.to_s(base=16)
                    end
                  when :element_text
                    if the_value.valid_time? || the_value.valid_date? || the_value.valid_datetime_nolocale? || the_value.valid_datetime?
                      db_content = reduce_to_datetime.call(the_value)
                    else
                      db_content = the_value
                    end
                  else
                    db_content = the_value
                  end
                  if db_content
                    the_result = db_content
                  else
                    raise Exception, "Could not cast the value to something useful: #{the_value.inspect}"
                  end
                end
                the_result
              end
              #
              find_property_records = Proc.new do |a_selector, a_container|
                a_result = []
                a_container.each do |item|
                  if item[(a_selector)]
                    a_result << item
                  end
                end
                a_result
              end
              find_element_records = Proc.new do |a_selector, a_container|
                a_result = []
                a_container.each do |item|
                  if item[(a_selector)]
                    a_result << item
                  end
                end
                a_result
              end
              found_list = []
              # criteria[:property] :
              # For all
              # {:property_name => {:equals => value}}
              # For :element_integer, :element_float, :element_bigdecimal
              # {:property_name => {:greater_than => value, :greater_or_equal => value, :less_than => value, :less_or_equal => value}}
              # For :element_datetime, Note: if you pass text as a date ::Chronic will be used to parse it.
              # {:property_name => {:at => value, :before => value, :at_or_before => value, :after => value, :at_or_after => value, :between => <range-value>}
              # For Text, Binary
              # {:property_name => {:include => value}}
              # 
              # criteria[:element] :
              # similar to criteria[:property] except that the entire table for the type is searched and no property dereferencing needed.
              #
              if criteria[:property] || criteria[:element]
                # Expansion
                # Text Search: @connector[:text_page].where(::Sequel.like(:content,'%#{search_text}%'))
                # Binary Search: @connector[:binary_page].where(::Sequel.like(:content,'%#{byte_sequence}%'))
                # self.element_parent_address(the_table=:unspecified, the_dbid=0)
                if criteria[:property].is_a?(::Hash)
                  # Only ONE property key can be compared (TODO: expand to multiple keys)
                  property_matches = []
                  last_key = nil
                  #
                  criteria[:property].keys.each do |property_key|
                    # compare each key's value to qualify the parent object:
                    # {:html => {:include => "\n"}}
                    comparison_op = criteria[:property][(property_key)].keys[0].to_sym
                    if criteria[:property][(property_key)][(comparison_op)].is_any?(::String, ::Range) && [:at, :before, :after, :at_or_before, :at_or_after, :between].include?(comparison_op)
                      comparison_value = reduce_to_datetime.call(criteria[:property][(property_key)][(comparison_op)])
                      table_test = ::GxG::Database::Database::element_table_for_instance(comparison_value)
                    else
                      table_test = ::GxG::Database::Database::element_table_for_instance(criteria[:property][(property_key)][(comparison_op)])
                      comparison_value = db_content_value.call(criteria[:property][(property_key)][(comparison_op)])
                    end
                    #
                    if [:element_hash, :element_array].include?(table_test)
                      # Only properties with base elements can be compared - not structures (TODO: expand this)
                      log_warn("Attempted to compare a structure as a property value (not supported, ignoring).")
                      next
                    end
                    # Review : rewrite - adapt to new arch.
                    match_uuid_list = []
                    # comparison_value
                    @connector[:hash_properties].filter({:property => property_key.to_s}).each do |entry|
                      element_value = nil
                      case entry[:element]
                      when "element_boolean"
                        case entry[:element_boolean]
                        when -1
                          element_value = nil
                        when 0
                          element_value = false
                        when 1
                          element_value = nil
                        end
                      when "element_integer"
                        element_value = entry[:element_integer]
                      when "element_float"
                        element_value = entry[:element_float]
                      when "element_bigdecimal"
                        element_value = ::BigDecimal.new(entry[:element_bigdecimal].to_s)
                      when "element_datetime"
                        element_value = entry[:element_datetime]
                      when "element_text"
                        if entry[:element_text_uuid].to_s.size > 0
                          # Review: issue with Base64: decode64 mangles non-base64 text but does it w/o error now.
                          element_value = ""
                          @connector[:text_page].filter({:uuid => entry[:element_text_uuid].to_s}).order(:ordinal).each do |text_page|
                            element_value << text_page[:content]
                          end
                        else
                          element_value = entry[:element_text]
                        end
                      when "element_binary"
                        element_value = ::GxG::ByteArray.new
                        @connector[:binary_page].filter({:uuid => entry[:element_binary_uuid].to_s}).order(:ordinal).each do |binary_page|
                          element_value << binary_page[:content]
                        end
                      end
                      #
                      begin
                        case comparison_op
                        when :equals, :at
                          if element_value == comparison_value
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :greater_than, :after
                          if element_value > comparison_value
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :greater_or_equal, :at_or_after
                          if element_value >= comparison_value
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :less_than, :before
                          if element_value < comparison_value
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :less_or_equal, :at_or_before
                          if element_value <= comparison_value
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :between
                          if comparison_value.include?(element_value)
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :include
                          if element_value.to_s.include?(comparison_value.to_s)
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        when :match
                          if element_value.to_s.match(comparison_value)
                            match_uuid_list << entry[:parent_uuid].to_sym
                          end
                        end
                      rescue Exception => cast_error
                        # Probably a type casting error (comparison of dissimilar types)
                        next
                      end
                    end
                    #
                    match_uuid_list.each do |the_matched_uuid|
                      # Add to main found list
                      parent_record = @connector[:element_hash].select(:uuid, :version, :title).where({:uuid => the_matched_uuid.to_s}).first
                      if parent_record
                        new_record = {}
                        selected.each do |the_selected_key|
                          if parent_record.keys.include?(the_selected_key)
                            new_record[(the_selected_key)] = parent_record[(the_selected_key)]
                            if ::GxG::valid_uuid?(new_record[(the_selected_key)])
                              new_record[(the_selected_key)] = new_record[(the_selected_key)].to_sym
                            end
                          end
                        end
                        unless found_list.include?(new_record)
                          found_list << new_record
                        end
                      end
                    end
                    #
                    if last_key != property_key
                      last_key = property_key
                    end
                    #
                  end
                  #
                else
                  if criteria[:element].is_a?(::Array)
                    criteria[:element].each_with_index do |the_element, element_index|
                      comparison_op = criteria[:element][(element_index)].keys[0].to_sym
                      if criteria[:element][(element_index)][(comparison_op)].is_any?(::String, ::Range) && [:at, :before, :after, :at_or_before, :at_or_after, :between].include?(comparison_op)
                        comparison_value = reduce_to_datetime.call(criteria[:element][(element_index)][(comparison_op)])
                        element_table = ::GxG::Database::Database::element_table_for_instance(comparison_value)
                      else
                        element_table = ::GxG::Database::Database::element_table_for_instance(criteria[:element][(element_index)][(comparison_op)])
                        comparison_value = db_content_value.call(criteria[:element][(element_index)][(comparison_op)])
                      end
                      # Structural comparison not supported.
                      if [:element_hash, :element_array].include?(element_table)
                        log_warn("Attempted to compare a structure as an element (not supported, ignoring).")
                        next
                      end
                      match_uuid_list = []
                      # comparison_value
                      @connector[:array_elements].filter({:element => element_table.to_s}).each do |entry|
                        element_value = nil
                        case entry[:element]
                        when "element_boolean"
                          case entry[:element_boolean]
                          when -1
                            element_value = nil
                          when 0
                            element_value = false
                          when 1
                            element_value = nil
                          end
                        when "element_integer"
                          element_value = entry[:element_integer]
                        when "element_float"
                          element_value = entry[:element_float]
                        when "element_bigdecimal"
                          element_value = ::BigDecimal.new(entry[:element_bigdecimal].to_s)
                        when "element_datetime"
                          element_value = entry[:element_datetime]
                        when "element_text"
                          if entry[:element_text_uuid].to_s.size > 0
                            # Review: issue with Base64: decode64 mangles non-base64 text but does it w/o error now.
                            element_value = ""
                            @connector[:text_page].filter({:uuid => entry[:element_text_uuid].to_s}).order(:ordinal).each do |text_page|
                              element_value << text_page[:content]
                            end
                          else
                            element_value = entry[:element_text]
                          end
                        when "element_binary"
                          element_value = ::GxG::ByteArray.new
                          @connector[:binary_page].filter({:uuid => entry[:element_binary_uuid].to_s}).order(:ordinal).each do |binary_page|
                            element_value << binary_page[:content]
                          end
                        end
                        #
                        begin
                          case comparison_op
                          when :equals, :at
                            if element_value == comparison_value
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :greater_than, :after
                            if element_value > comparison_value
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :greater_or_equal, :at_or_after
                            if element_value >= comparison_value
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :less_than, :before
                            if element_value < comparison_value
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :less_or_equal, :at_or_before
                            if element_value <= comparison_value
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :between
                            if comparison_value.include?(element_value)
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :include
                            if element_value.to_s.include?(comparison_value.to_s)
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          when :match
                            if element_value.to_s.match(comparison_value)
                              match_uuid_list << entry[:parent_uuid].to_sym
                            end
                          end
                        rescue Exception => cast_error
                          # Probably a type casting error (comparison of dissimilar types)
                          next
                        end
                        # end - comparison loop
                      end
                      #
                      match_uuid_list.each do |the_matched_uuid|
                        # Add to main found list
                        parent_record = @connector[:element_array].select(:uuid, :version, :title).where({:uuid => the_matched_uuid.to_s}).first
                        if parent_record
                          new_record = {}
                          selected.each do |the_selected_key|
                            if parent_record.keys.include?(the_selected_key)
                              new_record[(the_selected_key)] = parent_record[(the_selected_key)]
                              if ::GxG::valid_uuid?(new_record[(the_selected_key)])
                                new_record[(the_selected_key)] = new_record[(the_selected_key)].to_sym
                              end
                            end
                          end
                          unless found_list.include?(new_record)
                            found_list << new_record
                          end
                        end
                      end
                      #
                      # unless last_index == element_index
                      #   last_index = element_index
                      # end
                    end
                    #
                  else
                    # Criteria Expansion Here
                  end
                end
              else
                @connector[:element_hash].filter(hash_criteria).each do |entry|
                  new_record = {}
                  selected.each do |the_key|
                    if ::GxG::valid_uuid?(entry[(the_key)])
                      new_record[(the_key)] = entry[(the_key)].to_sym
                    else
                      new_record[(the_key)] = entry[(the_key)]
                    end
                  end
                  found_list << new_record
                end
                #
                unless hash_criteria[:format]
                  @connector[:element_array].filter(array_criteria).each do |entry|
                    new_record = {}
                    selected.each do |the_key|
                      if ::GxG::valid_uuid?(entry[(the_key)])
                        new_record[(the_key)] = entry[(the_key)].to_sym
                      else
                        new_record[(the_key)] = entry[(the_key)]
                      end
                    end
                    found_list << new_record
                  end
                end
              end
              #
              # Sorting Options Here: (Expansion)
              if criteria[:order].is_any?(::Symbol, ::Hash)
                ascending = true
                sort_key = nil
                if criteria[:order].is_a?(::Hash)
                  if criteria[:order][:ascending].is_a?(::Symbol)
                    sort_key = criteria[:order][:ascending]
                  end
                  if criteria[:order][:descending].is_a?(::Symbol)
                    sort_key = criteria[:order][:descending]
                    ascending = false
                  end
                else
                  sort_key = criteria[:order]
                end
                if selected.include?(sort_key)
                  found_list = found_list.sort do |entry, another|
                    entry[(sort_key)] <=> another[(sort_key)]
                  end
                  unless ascending
                    found_list.reverse!
                  end
                end
              end
              # Impose result set limit and offset
              if limit.is_a?(::Integer)
                if found_list.size > 0
                  if (offset + (limit - 1)) <= (found_list.size - 1)
                    found_list = found_list[((offset)..(offset + (limit - 1)))]
                  else
                    if offset <= (found_list.size - 1)
                      found_list = found_list[((offset)..(-1))]
                    end
                  end
                end
              end
              #
              found_list.size.times do
                result << found_list.shift
              end
              #
            else
              raise Exception, "Database not available"
            end
          else
            raise Exception, "Attempted to access a defunct Database"
          end
        rescue Exception => the_error
          log_error({:error => the_error, :parameters => {:credential => (credential), :criteria => (criteria)}})
        end
        result
      end
      #
      def search_database(credential=nil, criteria={})
        # Usage: search_database(credential, {:ufs => "the.ufs.code", :properties => [{:the_property => {:equals => value}}]})
        #
        # criteria[:properties] :
        # For all
        # {:property_name => {:equals => value}}
        # For :element_integer, :element_float, :element_bigdecimal
        # {:property_name => {:greater_than => value, :greater_or_equal => value, :less_than => value, :less_or_equal => value}}
        # For :element_datetime, Note: if you pass text as a date ::Chronic will be used to parse it.
        # {:property_name => {:at => value, :before => value, :at_or_before => value, :after => value, :at_or_after => value, :between => <range-value>}
        # For Text, Binary
        # {:property_name => {:include => value}}
        # 
        # criteria[:element] :
        # similar to criteria[:property] except that the entire table for the type is searched and no property dereferencing needed.
        #
        result = []
        criterium = []
        criteria_error = false
        unless criteria.is_a?(::Hash)
          criteria_error = true
        end
        unless criteria_error
          common_criteria = criteria.clone
          properties = (common_criteria.delete(:properties) || [])
          unless properties.is_a?(::Array)
            criteria_error = true
          end
          elements = (common_criteria.delete(:elements) || [])
          unless elements.is_a?(::Array)
            criteria_error = true
          end
        end
        #
        unless criteria_error
          if properties.size > 0 && elements.size > 0
            criteria_error = true
            log_warn("You MUST select EITHER :properites OR :elements, not both.")
          end
        end
        #
        unless criteria_error
          # Prepare criterium
          if common_criteria[:select].is_a?(::Array)
            unless common_criteria[:select].include?(:uuid)
              common_criteria[:select] << :uuid
            end
          else
            common_criteria[:select] = [:uuid]
          end
          #
          if common_criteria[:ufs]
            criterium << {:ufs => common_criteria[:ufs]}
          end
          if common_criteria[:format]
            criterium << {:format => common_criteria[:format]}
          end
          #
          if properties.size > 0
            properties.each do |the_property_search|
              criterium << ((common_criteria.clone).merge({:property => the_property_search}))
            end
          end
          if elements.size > 0
            elements.each do |the_element_search|
              criterium << ((common_criteria.clone).merge({:element => the_element_search}))
            end
          end
        end
        #
        result_sets = []
        # if properties.size == 0 && elements.size == 0
        #   result_sets << self.uuid_list(credential, criteria)
        # else
          criterium.each do |the_criteria|
            result_sets << self.uuid_list(credential, the_criteria)
          end
        # end
        scores = {}
        result_sets.each do |the_result|
          the_result.each do |the_answer|
            if scores.keys.include?(the_answer[:uuid])
              scores[(the_answer[:uuid])] = (scores[(the_answer[:uuid])] + 1)
            else
              scores[(the_answer[:uuid])] = 1
            end
          end
        end
        scores.keys.each do |the_uuid|
          if scores[(the_uuid)] == result_sets.size
            result_sets[0].each do |the_record|
              if the_record[:uuid] == the_uuid
                result << the_record
                break
              end
            end
          end
        end
        #
        result
      end
      # Synchronize records: (and supports)
      #
      def synchronize_records(the_records=[], credential=nil, options={})
        # Review : rewrite for new architecture.
        result = {:status => :completed}
        #
        total_records_processed = 0
        total_formats_processed = 0
        # List of format uuids needed from the OTHER database to complete the sync.
        formats_needed = []
        # List of format records we are sharing.
        formats_provided = []
        # records on THIS database that are higher version than submitted version.
        updates_provided = []
        # In case something goes horribly wrong:
        clean_up_list = []
        #
        begin
          if self.alive?
            if self.open?
              unless ::GxG::valid_uuid?(credential)
                raise ArgumentError, "You MUST provide a valid UUID as credential."
              end
              #
              if the_records.is_a?(::String)
                if the_records.base64?
                  the_records = the_records.decode64
                end
                if the_records.json?
                  the_records = ::JSON.parse(the_records,{:symbolize_names => true})
                end
              end
              if the_records.is_a?(::Hash)
                the_records = [(the_records)]
              end
              unless the_records.is_a?(::Array)
                raise ArgumentError, "You MUST provide: Base64, JSON, Hash, or Array of operation Hashes."
              end
              # Process each operation in the_records, data is inline under :data key.
              the_records.each do |the_operation|
                if the_operation.is_a?(::Hash)
                  if [:merge, :delete, :fetch, :merge_format, :delete_format, :formats_provided, :formats_needed].include?(the_operation[:operation])
                    #
                    case the_operation[:operation]
                    when :merge
                      unless self.db_permissions()[:write]
                        raise Exception, "Attempted to alter a read-only database."
                      end
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if entry[:format]
                          unless self.format_list({:uuid => (entry[:format])}).size > 0
                            raise Exception, "Attempted to merge with unknown :format #{entry[:format].inspect}. Synchronize formats first, then records."
                          end
                        end
                        # fetch existing:
                        # if existing - compare versions - if greater provide, if lesser update, else add to db.
                        queue = [(entry)]
                        while queue.size > 0 do
                          record = queue.shift
                          if ::GxG::valid_uuid?(record[:uuid])
                            formatting = {:format => nil, :constraint => nil}
                            existing = self.retrieve_by_uuid(record[:uuid], credential)
                            unless existing
                              # Note: since there is no way to create a Persisted Object with a given UUID, this method is used to create the object: object will be updated later.
                              unless @connector[(record[:type].to_s.downcase.to_sym)].filter({:uuid => record[:uuid].to_s}).count > 0
                                # This prevents no-element-retrieved-due-to-permission issue causing an 'add duplicate uuid object' situation:
                                dbid = @connector[(record[:type].to_s.downcase.to_sym)].insert({:uuid => record[:uuid].to_s, :title => "Merged Persisted Object"})
                                self.assign_element_permission(record[:type].to_s.downcase.to_sym,dbid,credential,{:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                                #
                              end
                              existing = self.retrieve_by_uuid(record[:uuid], credential)
                            end
                            if existing
                              # ### Compare versions
                              if existing.version > record[:version]
                                action = :provide
                              else
                                if existing.version < record[:version]
                                  action = :update
                                else
                                  action = :ignore
                                end
                              end
                              # ### Take Action
                              case action
                              when :provide
                                updates_provided << {:operation => :merge, :data => [(existing.export())]}
                                existing.deactivate
                                total_records_processed += 1
                              when :update
                                # ### Prelude
                                if record[:format].to_s.size > 0
                                  formatting[:format] = record[:format].to_s
                                end
                                if record[:constraint].to_s.size > 0
                                  formatting[:constraint] = record[:constraint].to_s
                                end
                                clean_up_list << existing
                                existing.get_reservation()
                                unless existing.write_permission?() && existing.write_reserved?()
                                  raise Exception, "Failed to secure write permission and write reservation for this credential."
                                end
                                existing.title = (record[:title])
                                # ### Update Elements
                                if record[:content].is_a?(::Hash)
                                  # Review : What to do / how to handle formatted existing Hashes??
                                  unless existing.format
                                    # Eliminate keys that the imported record does not have. (tracking structural changes)
                                    existing.keys.each do |the_key|
                                      unless record[:content].keys.include?(the_key)
                                        temp_object = existing.delete(the_key)
                                        if temp_object.is_any?(::GxG::Database::PersistedArray, ::GxG::Database::PersistedHash)
                                          temp_object.destroy()
                                        end
                                      end
                                    end
                                  end
                                  record[:content].each_pair do |property, element_record|
                                    if element_record[:uuid]
                                      # ### Element is Hash or Array
                                      element = self.retrieve_by_uuid(element_record[:uuid], credential)
                                      unless element
                                        # ### Create blank element record and retrieve
                                        # Note: since there is no way to create a Persisted Object with a given UUID, this method is used to create the object: object will be updated later.
                                        unless @connector[(element_record[:type].to_s.downcase.to_sym)].filter({:uuid => element_record[:uuid].to_s}).count > 0
                                          # This prevents no-element-retrieved-due-to-permission issue causing an 'add duplicate uuid object' situation:
                                          dbid = @connector[(element_record[:type].to_s.downcase.to_sym)].insert({:uuid => element_record[:uuid].to_s, :title => "Merged Persisted Object"})
                                          self.assign_element_permission(element_record[:type].to_s.downcase.to_sym,dbid,credential,{:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                                          #
                                        end
                                        element = self.retrieve_by_uuid(element_record[:uuid], credential)
                                      end
                                      if element
                                        # ### Ensure Element Linking
                                        # Review : Warning - absence of a :write permission can bugger this up.
                                        clean_up_list << element
                                        element.get_reservation()
                                        unless element.write_permission?() && element.write_reserved?()
                                          raise Exception, "Failed to secure write permission and write reservation for this credential."
                                        end
                                        existing[(property)] = element
                                        # element.deactivate ??
                                      end
                                      # Note: return to processing queue to set its elements
                                      queue << element_record
                                    else
                                      # ### Base Element
                                      unless existing.version(property) > element_record[:version]
                                        the_content = nil
                                        case element_record[:type].to_s.downcase.to_sym
                                        when :element_boolean, :element_integer, :element_float
                                          the_content = element_record[:content]
                                        when :element_bigdecimal
                                          the_content = ::BigDecimal.new(element_record[:content].to_s)
                                        when :element_datetime
                                          the_content = ::DateTime::parse(element_record[:content].to_s)
                                        when :element_text
                                          the_content = element_record[:content].to_s
                                        when :element_binary
                                          the_content = ::GxG::ByteArray.new(element_record[:content].to_s.decode64)
                                        end
                                        existing[(property)] = the_content
                                      end
                                    end
                                  end
                                else
                                  if record[:content].is_a?(::Array)
                                    # Eliminate elements that the imported record does not have. (tracking structural changes)
                                    if existing.size > record[:content].size
                                      ((record[:content].size)..(existing.size - 1)).each do |the_indexer|
                                        temp_object = existing.delete_at(the_indexer)
                                        if temp_object.is_any?(::GxG::Database::PersistedArray, ::GxG::Database::PersistedHash)
                                          temp_object.destroy()
                                        end
                                      end
                                    end
                                    record[:content].each_with_index do |element_record, indexer|
                                      if element_record[:uuid]
                                        # ### Element is Hash or Array
                                        element = self.retrieve_by_uuid(element_record[:uuid], credential)
                                        unless element
                                          # ### Create blank element record and retrieve
                                          # Note: since there is no way to create a Persisted Object with a given UUID, this method is used to create the object: object will be updated later.
                                          unless @connector[(element_record[:type].to_s.downcase.to_sym)].filter({:uuid => element_record[:uuid].to_s}).count > 0
                                            # This prevents no-element-retrieved-due-to-permission issue causing an 'add duplicate uuid object' situation:
                                            dbid = @connector[(element_record[:type].to_s.downcase.to_sym)].insert({:uuid => element_record[:uuid].to_s, :title => "Merged Persisted Object"})
                                            self.assign_element_permission(element_record[:type].to_s.downcase.to_sym,dbid,credential,{:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read => true})
                                            #
                                          end
                                          element = self.retrieve_by_uuid(element_record[:uuid], credential)
                                        end
                                        if element
                                          # ### Ensure Element Linking
                                          # Review : Warning - absence of a :write permission can bugger this up.
                                          clean_up_list << element
                                          element.get_reservation()
                                          unless element.write_permission?() && element.write_reserved?()
                                            raise Exception, "Failed to secure write permission and write reservation for this credential."
                                          end
                                          existing[(indexer)] = element
                                          # element.deactivate ??
                                        end
                                        # Note: return to processing queue to set its elements
                                        queue << element_record
                                      else
                                        # ### Base Element
                                        unless existing.version(indexer) > element_record[:version]
                                          the_content = nil
                                          case element_record[:type].to_s.downcase.to_sym
                                          when :element_boolean, :element_integer, :element_float
                                            the_content = element_record[:content]
                                          when :element_bigdecimal
                                            the_content = ::BigDecimal.new(element_record[:content].to_s)
                                          when :element_datetime
                                            the_content = ::DateTime::parse(element_record[:content].to_s)
                                          when :element_text
                                            the_content = element_record[:content].to_s
                                          when :element_binary
                                            the_content = ::GxG::ByteArray.new(element_record[:content].to_s.decode64)
                                          end
                                          existing[(indexer)] = the_content
                                        end
                                      end
                                      #
                                    end
                                  end
                                end
                                # ### Set Fromatting / Constraints
                                if existing.is_a?(::GxG::Database::PersistedHash)
                                  if formatting[:format].to_s.size > 0
                                    existing.format = (formatting[:format])
                                  end
                                end
                                if existing.is_a?(::GxG::Database::PersistedArray)
                                  if formatting[:constraint].to_s.size > 0
                                    existing.constraint = (formatting[:constraint])
                                  end
                                end
                                # ### Conclude Existing
                                existing.version = (record[:version])
                                existing.save
                                existing.deactivate
                                total_records_processed += 1
                              end
                            end
                          end
                        end
                        #
                      end
                    when :delete
                      unless self.db_permissions()[:write]
                        raise Exception, "Attempted to alter a read-only database."
                      end
                      #
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          existing = self.retrieve_by_uuid(entry[:uuid].to_sym, credential)
                          if existing
                            the_address = existing.db_address()
                            existing.deactivate
                            if self.element_destroy(credential,the_address[:table],the_address[:dbid])
                              total_records_processed += 1
                            else
                              log_warn("Record #{entry[:uuid].inspect} was not deleted.")
                            end
                          else
                            log_warn("Record #{entry[:uuid].inspect} was not found.")
                          end
                        else
                          log_warn("Invalid UUID specifier (ignoring): #{entry[:uuid].inspect}")
                        end
                      end
                      #
                    when :fetch
                      # wrap export record in a :merge operation and add to updates_provided.
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          existing = self.retrieve_by_uuid(entry[:uuid].to_sym, credential)
                          if existing
                            updates_provided << {:operation => :merge, :data => [(existing.export())]}
                            existing.deactivate
                            total_records_processed += 1
                          else
                            log_warn("Record #{entry[:uuid].inspect} was not found.")
                          end
                        else
                          log_warn("Invalid UUID specifier (ignoring): #{entry[:uuid].inspect}")
                        end
                      end
                      #
                    when :merge_format
                      unless self.db_permissions()[:write]
                        raise Exception, "Attempted to alter a read-only database."
                      end
                      # add format record if missing - check for existing, and provide if ours is newer.
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          existing = self.format_load({:uuid => entry[:uuid].to_sym})
                          if existing.is_a?(::Hash)
                            if existing[:version] < entry[:version]
                              if self.format_update(entry)
                                total_formats_processed += 1
                              else
                                log_warn("Could not update Format #{entry[:uuid].inspect}")
                              end
                            end
                            if existing[:version] > entry[:version]
                              unless formats_provided.include?(existing)
                                formats_provided << existing
                                total_formats_processed += 1
                              end
                            end
                          else
                            if self.format_create(entry)
                              total_formats_processed += 1
                            else
                              log_warn("Could not create Format #{entry[:uuid].inspect}")
                            end
                          end
                        else
                          log_warn("Invalid Format specifier (ignoring): #{entry[:uuid].inspect}")
                        end
                      end
                    when :delete_format
                      unless self.db_permissions()[:write]
                        raise Exception, "Attempted to alter a read-only database."
                      end
                      # If the format is in use, log_warn that you're ignoring the directive.
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          if @connector[:element_hash].filter({:format => entry[:uuid].to_s}).count == 0 && @connector[:element_array].filter({:constraint => entry[:uuid].to_s}).count == 0
                            # Not in use, safe to delete
                            if self.format_destroy({:uuid => entry[:uuid].to_sym})
                              total_formats_processed += 1
                            end
                          else
                            log_warn("Format #{entry[:uuid].inspect} in use (ignorning).")
                          end
                        else
                          log_warn("Invalid format specifier on :delete directive (ignorning): #{entry[:uuid].inspect}")
                        end
                      end
                    when :formats_provided
                      unless self.db_permissions()[:write]
                        raise Exception, "Attempted to alter a read-only database."
                      end
                      # compare uuids against db-installed formats and add to formats_needed if missing.
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          if self.format_list({:uuid => (entry[:uuid])}).size == 0
                            record = {:uuid => (entry[:uuid].to_sym)}
                            unless formats_needed.include?(record)
                              formats_needed << record
                              total_formats_processed += 1
                            end
                          end
                        else
                          log_warn("Invalid Format specifier (ignoring): #{entry[:uuid].inspect}")
                        end
                      end
                    when :formats_needed
                      # Gather up existing format records to share.
                      manifest = []
                      if the_operation[:data].is_a?(::Array)
                        manifest = the_operation[:data]
                      else
                        if the_operation[:data].is_a?(::Hash)
                          manifest = [(the_operation[:data])]
                        else
                          log_warn("Invalid record sepecifier or manifiest (ignoring): #{the_operation[:data].inspect}")
                        end
                      end
                      manifest.each do |entry|
                        if ::GxG::valid_uuid?(entry[:uuid])
                          existing = self.format_load({:uuid => entry[:uuid].to_sym})
                          if existing.is_a?(::Hash)
                            unless formats_provided.include?(existing)
                              formats_provided << existing
                              total_formats_processed += 1
                            end
                          end
                        else
                          log_warn("Invalid Format specifier (ignoring): #{entry[:uuid].inspect}")
                        end
                      end
                      #
                    end
                  else
                    log_warn("Invalid operation (ignoring): #{the_operation[:operation].inspect}")
                  end
                else
                  raise Exception, "Invalid formatted operation passed (MUST be a Hash): #{the_operation.inspect}"
                end
              end
              #
            else
              raise Exception, "Database not available."
            end
          else
            raise Exception, "Attempted to access a defunct database."
          end
        rescue Exception => the_error
          clean_up_list.each do |the_object|
            if the_object.alive?
              the_object.release_reservation()
              the_object.deactivate()
            end
          end
          result[:status] = :failed
          #log_error({:error => the_error, :parameters => {:records => (the_records), :options => (options)}})
          log_error({:error => the_error, :parameters => {}})
        end
        result[:formats_needed] = formats_needed
        result[:formats_provided] = formats_provided
        result[:record_updates] = updates_provided
        result[:records_processed] = total_records_processed
        result[:formats_processed] = total_formats_processed
        result
      end
      #
      def sync_export(credential=nil, uuid_list=[], options={})
        result = {:formats => {}, :records => []}
        if uuid_list.is_any?(::Array, ::GxG::Database::PersistedArray)
          uuid_list.each do |the_reference|
            the_uuid = the_reference
            if ::GxG::valid_uuid?(the_uuid)
              the_object = self.retrieve_by_uuid(the_uuid, credential)
              if the_object
                object_record = the_object.export()
                object_record.search do |item,selector,container|
                  if selector == :format || selector == :constraint
                    if item.to_s.size > 0
                      format_uuid = item
                      unless result[:formats][(format_uuid.to_s.to_sym)].is_a?(::Hash)
                        format_sample = self.format_load({:uuid => format_uuid.to_s.to_sym})
                        format_sample[:content] = format_sample[:content].gxg_export()
                        result[:formats][(format_uuid.to_s.to_sym)] = format_sample
                      end
                    end
                  end
                end
                result[:records] << object_record
                #
              end
            end
          end
        end
        result
      end
      #
      def sync_import(credential=nil, the_records={:formats => {}, :records => []}, options={})
        result = false
        #
        if the_records.is_a?(::Hash)
          if the_records[:formats].is_a?(::Hash)
            op_frame = {:operation => :merge_format, :data => []}
            the_records[:formats].each_pair do |the_uuid, the_format_record|
              if the_format_record[:version].is_a?(::String)
                the_format_record[:version] = ::BigDecimal.new(the_format_record[:version])
              end
              # gxg_import format content prior to sync update op
              the_format_record[:content] = ::Hash.gxg_import(the_format_record[:content])
              op_frame[:data] << the_format_record
            end
            if op_frame[:data].size > 0
              self.synchronize_records([(op_frame)],credential)
            end
          end
          #
          if the_records[:records].is_a?(::Array)
            if the_records[:records].size > 0
              the_records[:records].each do |the_record|
                the_record.search do |value, selector, container|
                  if selector == :version && value.is_a?(::String)
                    container[(selector)] = ::BigDecimal.new(value)
                  end
                end
              end
              self.synchronize_records([{:operation => :merge, :data => the_records[:records]}],credential)
              result = true
            end
          end
        end
        #
        result
      end
      # Class method for importing an export record as a detached structure.
      def self.detached_import(import_record=nil)
        result = nil
        unless import_record.is_any?(::Hash, ::GxG::Database::PersistedHash)
            raise Exception, "Malformed import record passed."
        end
        # {:type => :element_hash, :uuid => @uuid.clone, :title => @title.clone, :version => @version.clone, :format => @format.clone, :content => {}}
        import_db = [{:target => ::GxG::Database::DetachedHash.new, :record => import_record}]
        result =  import_db[0][:target]
        while import_db.size > 0 do
            entry = import_db.shift
            case entry[:record][:type].to_s.to_sym
            when :element_hash
                entry[:target].uuid = entry[:record][:uuid].to_s.to_sym
                entry[:target].title = entry[:record][:title].to_s
                 entry[:record][:content].keys.each do |the_key|
                     case entry[:record][:content][(the_key)][:type].to_s.to_sym
                     when :element_hash
                         new_target = GxG::Database::DetachedHash.new
                         entry[:target][(the_key)] = new_target
                         import_db << {:target => new_target, :record => (entry[:record][:content][(the_key)])}
                         entry[:target][(the_key)].parent = (entry[:target])
                     when :element_array
                         new_target = GxG::Database::DetachedArray.new
                         entry[:target][(the_key)] = new_target
                         import_db << {:target => new_target, :record => (entry[:record][:content][(the_key)])}
                         entry[:target][(the_key)].parent = (entry[:target])
                     when :element_boolean, :element_integer, :element_float, :element_text
                         entry[:target][(the_key)] = entry[:record][:content][(the_key)][:content]
                      when :element_bigdecimal
                          entry[:target][(the_key)] = ::BigDecimal.new(entry[:record][:content][(the_key)][:content].to_s)
                      when :element_datetime
                        entry[:target][(the_key)] = ::Chronic::parse(entry[:record][:content][(the_key)][:content].to_s)
                      when :element_binary
                        entry[:target][(the_key)] = ::GxG::ByteArray.new(entry[:record][:content][(the_key)][:content].to_s.decode64)
                     end
                 end
                entry[:target].version = ::BigDecimal.new(entry[:record][:version].to_s)
                entry[:target].format = entry[:record][:format].to_s.to_sym
            when :element_array
                entry[:target].uuid = entry[:record][:uuid].to_s.to_sym
                entry[:target].title = entry[:record][:title].to_s
                 entry[:record][:content].each_index do |indexer|
                      case entry[:record][:content][(indexer)][:type].to_s.to_sym
                      when :element_hash
                         new_target = GxG::Database::DetachedHash.new
                         entry[:target][(indexer)] = new_target
                         import_db << {:target => new_target, :record => (entry[:record][:content][(indexer)])}
                         entry[:target][(indexer)].parent =(entry[:target])
                      when :element_array
                         new_target = GxG::Database::DetachedArray.new
                         entry[:target][(indexer)] = new_target
                         import_db << {:target => new_target, :record => (entry[:record][:content][(indexer)])}
                         entry[:target][(indexer)].parent = (entry[:target])
                      when :element_boolean, :element_integer, :element_float, :element_text
                         entry[:target][(indexer)] = entry[:record][:content][(indexer)][:content]
                      when :element_bigdecimal
                          entry[:target][(indexer)] = ::BigDecimal.new(entry[:record][:content][(indexer)][:content].to_s)
                      when :element_datetime
                        entry[:target][(indexer)] = ::Chronic::parse(entry[:record][:content][(indexer)][:content].to_s)
                      when :element_binary
                        entry[:target][(indexer)] = ::GxG::ByteArray.new(entry[:record][:content][(indexer)][:content].to_s.decode64)
                      end
                 end
                entry[:target].version = ::BigDecimal.new(entry[:record][:version].to_s)
                entry[:target].constraint = entry[:record][:constraint].to_s.to_sym
            end
        end
        #
        result
      end
      # Class method to import an export package as a detached object.
      def self.detached_package_import(the_records={:formats => {}, :records => []}, options={})
        result = []
        #
        if the_records.is_a?(::Hash)
          if the_records[:formats].is_a?(::Hash)
            op_frame = {:operation => :merge_format, :data => []}
            the_records[:formats].each_pair do |the_uuid, the_format_record|
              if the_format_record[:version].is_a?(::String)
                the_format_record[:version] = ::BigDecimal.new(the_format_record[:version])
              end
              # gxg_import format content prior to sync update op
              the_format_record[:content] = ::Hash.gxg_import(the_format_record[:content])
              # Add to ::GxG::DB[:formats] ??
              unless ::GxG::DB[:formats][(the_uuid.to_s.to_sym)]
                # ?? Review : thread safety ??
                ::GxG::DB[:formats][(the_uuid.to_s.to_sym)] = the_format_record
              end
              op_frame[:data] << the_format_record
            end
            if op_frame[:data].size > 0
              ::GxG::DB[:roles][:formats].synchronize_records([(op_frame)],::GxG::DB[:administrator])
            end
          end
          #
          if the_records[:records].is_a?(::Array)
            if the_records[:records].size > 0
              the_records[:records].each do |the_record|
                the_record.search do |value, selector, container|
                  if selector == :version && value.is_a?(::String)
                    container[(selector)] = ::BigDecimal.new(value)
                  end
                end
                #
                result << ::GxG::Database::detached_import(the_record)
                #
              end
            end
          end
        end
        #
        result
      end
      #
      # ### Utility methods
      def clear_all_element_locks()
        # for when boo-boos happen
        if self.open?()
          if self.db_permissions()[:write]
            @connector[:element_locks].filter({}).delete
          end
        end
      end
      #
      # ### Various methods
      # Comm objects cannot be serialized - return encoded nil
      def serialize()
        "marshal:BAgw"
      end
      #
      # Comm objects cannot be cloned - returns nil
      def initialize_clone
        nil
      end
      alias :initialize_dup :initialize_clone
      alias :dup :initialize_clone
      def clone()
        initialize_clone
      end
      #
      def initialize(connection = nil, options={})
        # TODO: require :credential (access privs)
        super()
        @credential = nil
        @url = options[:url]
        @base_permissions = {:execute => false, :rename => false, :move => false, :destroy => false, :create => false, :write => false, :read => false}
        #
        if connection.is_a?(::Sequel::Database)
          @connector = connection
          #
          @active = false
          unless open?()
            raise Exception, "Unable to connect with the database"
          end
          # 
          @scheme = @url.scheme.to_s.to_sym
          case @scheme
          when :sqlite, :sqlite3
            @connector.run("PRAGMA page_size=65536")
            @connector.run("PRAGMA max_page_count=281474976710656")
            @connector.run("PRAGMA encoding='UTF-8'")
          when :mysql, :mysql2
            @connector.run("SET GLOBAL max_allowed_packet=17825792;")
            @connector.run("SET NAMES 'utf8' COLLATE 'utf8_general_ci';")
            @connector.run("SET collation_connection = 'utf8_general_ci';")
          when :postgres
            # place holder
          end
        else
          raise Exception, "Invalid db connection"
        end
        # characterize basic effective permissions
        begin
          formatted = db_formatted?()
          @base_permissions[:read] = true
          @base_permissions[:execute] = true
        rescue Exception => the_error
          formatted = false
          raise Exception, "Lack read permissions to the database"
        end
        #
        unless options[:read_only]
          if formatted
            begin
              dbid = @connector[:text_page].insert()
            rescue Exception => the_error
              dbid = nil
            end
            if dbid.is_a?(::Integer)
              @connector[:text_page].filter({:dbid => (dbid)}).delete
              @base_permissions[:write] = true
              @base_permissions[:create] = true
              @base_permissions[:destroy] = true
              @base_permissions[:rename] = true
              @base_permissions[:move] = true
            end
          else
            begin
              test_table_name = ::GxG::uuid_generate().gsub("-","")
              while (@connector.table_exists?(test_table_name.to_sym)) do
                test_table_name = ::GxG::uuid_generate().gsub("-","")
              end
              @connector.create_table(test_table_name.to_sym) do
                primary_key :dbid
              end
              @connector.drop_table(test_table_name.to_sym)
              @base_permissions[:write] = true
              @base_permissions[:create] = true
              @base_permissions[:destroy] = true
              @base_permissions[:rename] = true
              @base_permissions[:move] = true
            rescue Exception => the_error
              # Read-only Database
            end
          end
        end
        #
        @base_permissions.freeze
        #
        unless formatted
          if @base_permissions[:write]
            db_format
            unless db_formatted?()
              @active = false
              raise Exception, "Unable to format the database for use"
            end
          else
            raise Exception, "Unable to format a read-only database"
          end
        end
        #
        @authority = nil
        @db_list = []
        if options[:authority].is_any?(::GxG::Database::Database, ::GxG::Database::LDAPAuthority)
          @authority = options[:authority]
          @authority.db_register(self)
        end
        #
        unless @authority
          unless self.role_exist?("Administrators")
            if @base_permissions[:write]
              if self.user_id_available?("root")
                self.user_create("root","password")
                temp_cred = self.user_credential("root","password")
                temp_group = self.role_create("Administrators")
                self.role_add_user(temp_group,temp_cred)
                #
                dev_group = self.role_create("Developers")
                dsn_group = self.role_create("Designers")
                usr_group = self.role_create("Users")
                #
                self[:system_credentials] = {:administrator => temp_cred, :administrators => temp_group, :developers => dev_group, :designers => dsn_group, :users => usr_group}
                self[:permission_policy] = [{:event => :extend, :credential => :any, :action => {:extend_permissions => temp_group}}]
                #
              end
              if self.user_id_available?("public")
                self.user_create("public","password", "00000000-0000-4000-0000-000000000000")
              end
            end
          end
        end
        #
        permission_policy_load
        self
      end
      #
    end
    #
  end
  #
end
#
require File.expand_path("./gxg_database_persistedarray.rb",File.dirname(__FILE__))
require File.expand_path("./gxg_database_persistedhash.rb",File.dirname(__FILE__))
#
class Hash
  #
  def persist(credential=::GxG::DB[:administrator], to_db=:data)
    result = nil
    database = ::GxG::DB[:roles][(to_db)]
    if database.is_a?(::GxG::Database::Database)
      result = database.try_persist(self, credential)
    end
    result
  end
  #
end
#
class Array
  #
  def persist(credential=::GxG::DB[:administrator], to_db=:data)
    result = nil
    database = ::GxG::DB[:roles][(to_db)]
    if database.is_a?(::GxG::Database::Database)
      result = database.try_persist(self, credential)
    end
    result
  end
  #
end
