space system
{
    class array_value
    {
        key
        value

        array_value(key_set)
        { 
            key = key_set
            value = null
        }

        array_value(key_set  value_set)
        {
           key = key_set
           value = value_set
        }

        operator<(av)
        {
           return key < av.key
        }

        operator string()
        {
               return (string)value
        }

    }

    class array
    {
       tree
       iterator
       key_type
       data_type

       array() { tree = {} }

       erase() { tree = {} }

       iterate() { iterator = tree.header  }

       next() {iterator = iterator.next() return iterator.halt }

       add(key value)
       {
           tree << new array_value(key value)
        }

       contains(key)
       {
          return tree.contains_for_array(key)
       }

       begin { get { return tree.header.left } }

       end { get { return tree.header } }

       operator<(a)
       {
           if keys < a.keys  // compare the key sets first.
               return true
           else if a.keys < keys
               return false
           else                // the key sets are equal therefore compare array elements.
           {
               first1 = begin
               last1 = end
               first2 = a.begin
               last2 = a.end

               while first1 != last1 && first2 != last2
               {
                   if first1.data.value < first2.data.value
                       return true
                    else
                    {
                        if first2.data.value < first1.data.value
                           return false
                         else
                         {
                             first1 = first1.next
                             first2 = first2.next
                         }
                    }
               }

               return false
           }
       }

       operator==(compare) // equals and not equals derive from operator<
       {
           if this < compare return false
           if compare < this return false
           return true
       }

       operator!=(compare)
       {
            if this < compare return true
            if compare < this return true
            return false
       }

       operator<<(e)
       {
         if !empty
              this[last + 1] = e
          else
              this[new integer(0)] = e
          return this
       }

       operator[key]
       {
          set
          {
              if empty { key_type = key.type() data_type = value.type() }
              tree << new array_value(key value)
          }
          get
          {
             result = tree.get(new array_value(key))
             return result.value
          }
       }

       operator>>(key)
       {
           tree >> new array_value(key)
           return this
       }       

        empty
        {
            get
            {
                return tree.count == 0
            }  
        }

        count
        {
            get
            {
                return tree.count
            }  
        }

       operator string()
       {
          out = "["
          first1 = begin
          last1 = end
          while first1 != last1 
          {
              out = out + (string)first1.data.value
              first1 = first1.next()
              if first1 != last1 out = out + ","
          }
          out = out + "]"
          return out
       }

       keys // return the set of keys of the array.
       {
           get
           {
              k = {}
              for each in tree k << item.key
              return k
           }
       }

       values // return the set of keys of the array.
       {
           get
           {
              v = []
              for tree v << item.value
              return v
           }
       }

       serialize(oarchive)
       {
         oarchive << count
         oarchive << key_type
         oarchive << data_type
         b = begin
         e = end
         while b != e
         {
           oarchive << b.data.key
           oarchive << b.data.value
           b = b.next()
         }
       }

       deserialize(iarchive)
       {
           c = 0           
           iarchive >> c
           key_type_string = ""
           iarchive >> key_type_string
           data_type_string = ""
           iarchive >> data_type_string
           i = 0
           while i < c 
           {
               key = create_class(key_type_string)
               k = key.refresh()
               data = create_class(data_type_string)
               d = data.refresh()
               iarchive >> k
               iarchive >> d
               this[k] = d
               i++
           } 
       }

       operator+(p)
       {
           out = []
           first1 = begin
           last1 = end
           first2 = p.begin
           last2 = p.end
           while first1 != last1 && first2 != last2
           {
               out[first1.data.key] = first1.data.value + first2.data.value
               first1 = first1.next()
               first2 = first2.next()
           }
           return out
       }
  
       operator-(p)
       {
           out = []
           first1 = begin
           last1 = end
           first2 = p.begin
           last2 = p.end
           while first1 != last1 && first2 != last2
           {
              out[first1.data.key] = first1.data.value - first2.data.value
              first1 = first1.next()
              first2 = first2.next()
           }
           return out
       }

       operator*(o)
       {
           out = []
          first1 = begin
          last1 = end
          while first1 != last1
          {
              out[first1.data.key] = first1.data.value * o
              first1 = first1.next()
          }
          return out
      }

      operator/(o)
      {
         out = []
         first1 = begin
         last1 = end
         while first1 != last1
         {
             out[first1.data.key] = first1.data.value / o
            first1 = first1.next()
         }
         return out
      }

      rows
      {
         get
         {
            return tree.right_most.data.key + 1
         }
      }

       operator@(o) // dot product
       {
          if rows != o.rows throw "rows mismatch"
          result = 0
          row_count = rows
          i = +a
          while i < row_count
          {
              product = this[i] * o[i]
              result = result + product
              i++
           }
           return result
       }   

       sort
       {
           get
           {
               sort_bag = new bag()
               for each in tree sort_bag << item.value
               g = []
               for each in sort_bag {g << item}
               return g
           }
       }

       last // returns the value of the last element in the vector.
       { 
            get
             {
                 if empty
                     throw "empty vector"
                  else
                    return tree.right_most.data.key
            }
       }

       reverse
       {
           get
           {
               rev = []
               e = tree.header.right
               while !e.is_header
               {
                   rev << e.data.value
                   e = e.previous()  
               }
               return rev
           }
       }
   }
}