# == Schema Information
# Schema version: 51
#
# Table name: akapit_transzy
#
#  akapit_transzy_id :integer         primary key
#  akapit_id         :integer         not null
#  transza_id        :integer         not null
#  status            :integer         default(0), not null
#  odrzucony         :boolean         
#  uzytkownik_id     :integer         
#  created_at        :timestamp       
#  updated_at        :timestamp       
#  blizniaczy_id     :integer         
#

 #
 # This file is part of the Anotatornia suite.
 # 
 # Copyright © 2007, 2008, 2009, 2010 by Instytut Podstaw Informatyki
 # Polskiej Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 # Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 # 
 # This file may be distributed and/or modified under the terms of the
 # GNU General Public License version 3 as published by the Free Software
 # Foundation and appearing in the file COPYING included in the packaging
 # of this file.  (See http://www.gnu.org/licenses/translations.html for
 # unofficial translations.)
 # 
 # A commercial license is available from IPI PAN (contact
 # Michal.Ciesiolka.waw.pl or ipi.waw.pl for more
 # information).  Licensees holding a valid commercial license from IPI
 # PAN may use this file in accordance with that license.
 # 
 # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 # THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 # PURPOSE.
 #

require 'ramkowanie'


class AkapitTranszy < ActiveRecord::Base
  
  belongs_to :akapit
  belongs_to :transza
  ## has_many :komentarz, :order => :komentarz_id
  # nie has many, tylko subtelniej, bo będziemy wybierać komentarze do akapit #{akapit}, 
  # a nie do #{akapit_transzy}, albo do #{uzytkownik}-a (może się zdarzyć, 
  # w przypadku odebrania transzy, że komentarze do #akapit_transzy nie są danego
  # użytkownika. Wtedy na dzień dobry nie chcemy ich pokazywać. 
  # Z kolei dopóki akapit nie jest zweryfikowany, #akapit_transzy nie ma przypisanego #{uzytkownik}-a.
  has_many :fraza_anot, :order => "token_id_pocz, token_id_kon", :dependent => :destroy
  # podwójne porządkowanie fraz ze względu na przyszłe dopuszczenie zagnieżdżeń
  # klauzula #{:dependent => destroy} jest konieczna, by działała metoda #{delete_all}.


  ##  has_one :finitywna, :class_name => "FrazaAnot", 
  ##  :conditions => {:fraza_typ_id => FrazaTyp.find_id( 'VP' )}

  has_one :bliźniaczy, :class_name => "AkapitTranszy", 
  :foreign_key => "blizniaczy_id"
  

  has_many :interpretacja_anot, :order => "token_id",  :dependent => :destroy
  has_many :sens_anot, :order => "token_id",  :dependent => :destroy


  has_one :statusy 

  has_many :sg_variant_anot,
  :order => "sg_variant_id", :dependent => :destroy 

  has_many :koniec_zdania_anot, :order => "token_id", :dependent => :destroy

  def   sg_choice
    self.akapit.sg_choice
  end


  def ma_Status?( comparison, status_symb)
    # używana w \file{application.rb}
    return self.status.send( comparison, STATI[status_symb] )
  end
  

  
  def self.status1_2( status_symbol )
    ##    logger.info "@@@@@ AKapitTranszy.status1_2 wołany od #{status_symbol.inspect}"

    # #:anotaśne i~#:oczekujące obsługujemy w~#{status_betw}.

    if status_symbol == :zakończony
      status1 = STATI[ :zweryfikowany ]
      status2 = STATI[ :zweryfikowany ] + 1000

    elsif status_symbol == :rozbieżny
      status1 = STATI[ :zatwierdzony ] + 1
      status2 = STATI[ :zweryfikowany ] - 1

    elsif status_symbol == :podsądny
      status1 = STATI[ :do_osądzenia ] 
      status2 = STATI[ :osądzany ]

    elsif status_symbol.kind_of?(Array)
      status1 = STATI[ status_symbol[0] ]
      status2 = STATI[ status_symbol[1] ]

    else
      status1 = STATI[ status_symbol ]
      status2 = status1
    end
    wynik = [status1, status2]
    ##    logger.info "                        #{wynik.inspect}"
    wynik
  end # of #{self.status1_2}

  
  def self.status_est?( le_status_en_question, comparison, le_symbol_de_status )
    le_status_en_question.send( comparison, STATI[le_symbol_de_status] )
  end
  
  
  def self.editable_par_annoteur?( lestatus )
    # tę metodę wołamy by sprawdzić, czy status akapitu pozwala anotatorowi go anotować. Zarządca/Arbiter zawsze może go anotować, o ile jest na danym poziomie dopuszczony do anotacji.
    self.status_est?( lestatus,  :<, :do_osądzenia ) and
      self.status_est?( lestatus, :>=, :dopuszczony )
  end
  
  def self.confirmant?(lestatus)
    # tak ma być, bo przy wyświetlaniu listy akapitów pytamy, czy ma być "oglądaj" czy "anotuj"
    # więc #:zweryfikowany też ma tu wpadać.
    self.status_est?( lestatus, :>=, :zatwierdzony )
  end
  

  if DlaEli.nk

    @@poziomy_x = PoziomyAnotacji.poziomy_x

    @@poziomy_działające = PoziomyAnotacji.działające
    
    STATI = PoziomyAnotacji::STATI
    STATI_obniz = PoziomyAnotacji::STATI_obniz
    STATI_podnies = PoziomyAnotacji::STATI_podnies
    STATI_tekst = PoziomyAnotacji::STATI_tekst
    STATI_kr = PoziomyAnotacji::STATI_kr
    

    def statusek( poziom )
      self.statusy.send( poziom )
    end # of #  statusek
    
    def ma_status?( poziom, comparison, status_symb )
      if status_symb == :anotaśne
        return [ STATI[:dopuszczony], STATI[ :do_poprawki ] ].include?( self.statusek( poziom) )
      else
        return self.statusek( poziom ).send( comparison, STATI[status_symb] )
      end
    end
    
    def status_html
      akats = self.statusy
      stekst = @@poziomy_działające.collect{ |poz|
        PoziomyAnotacji::NAZWY[ poz ][:kr] + ':<b>' +
        STATI_kr[akats.send( poz )] +
        if akats.send( "#{poz}_odrzucony?" )
          " ODRZUCONY!"
        else ''
        end + '</b>'
      }.join(' | ')
    end

    
    def edytowalny_przez_anotatora?( poziom )
      self.ma_status?( poziom, :>=, :dopuszczony ) and
        self.ma_status?( poziom, :<, :do_osądzenia )
    end# of #{edytowalny_przez_anotatora?}\,.


    def self.poziomy_dostępne( akat_id, rola_id, parhasz={} )
      self.find( akat_id ).poziomy_dostępne( rola_id, parhasz )
    end# of \rb{self.poziomy_dostępne}


    def poziomy_dostępne( rola_id, parhasz={} )
      if Rola.anotator?( rola_id ) 
        pozdost = []
        @@poziomy_działające.each{ |poz|
          pozdost << poz if self.edytowalny_przez_anotatora?( poz ) }
      elsif Rola.zarzadca?( rola_id )
        pozdost = self.poziomy_o_statusie( :>=, :dopuszczony )
        pozdost &= self.poziomy_o_statusie( :<, :zweryfikowany ) if parhasz[ :jak_anotator ]
        pozdost -= [ :segmentation ] if # segmentacji raz przyklepanej nie można zmienić.
          parhasz[ :segmentation_specjalnie ] and 
          self.ma_status?( :segmentation, :>=, :zweryfikowany )
      else pozdost = []
      end
      
      pozdost &= PoziomyAnotacji.działające
      if phpp = parhasz[ :poziomy_pokaźne ]
        pozdost &= phpp
      end

      return pozdost
    end# of #{poziomy_dostępne}


    def poziomy_anotaśne( rola_id, parhasz={} )
      if Rola.anotator?( rola_id ) 
        pozano = []
        @@poziomy_działające.each{ |poz|
          if self.edytowalny_przez_anotatora?( poz )  and self.ma_status?( poz, :whatever, :anotaśne )
            pozano << poz
          end 
        }
      elsif Rola.zarzadca?( rola_id )
        pozano = self.poziomy_o_statusie( :>=, :dopuszczony )
        pozano &= self.poziomy_o_statusie( :<, :zweryfikowany ) if parhasz[ :jak_anotator ]
        pozano -= [ :segmentation ] if # segmentacji raz przyklepanej nie można zmienić.
          parhasz[ :segmentation_specjalnie ] and 
          self.ma_status?( :segmentation, :>=, :zweryfikowany )
      else pozano = []
      end
      
      pozano &= PoziomyAnotacji.działające
      if phpp = parhasz[ :poziomy_pokaźne ]
        pozano &= phpp
      end

      return pozano
    end# of #{poziomy_dostępne}



    def poziomy_max_anot

    end # of #poziomy_max_anot


    def poziomy_o_statusie( comparison_symbol, status_symbol )
      @@poziomy_x.collect{ |poz|
        poz if   self.ma_status?( poz, comparison_symbol, status_symbol )
      }.compact
    end # of #poziomy_dopuszczone
    
  end# of #{if nk}
    
# informacja, czy akapit zostało odrzucony, jest w kolumnie odrzucony

  def get_uzid( session_uzid=nil )
    # zakładamy, że użytkownik akapit transzy nie zmieni się w trakcie trwania tej instancji 
    unless @uzid
      @uzid = self.uzytkownik_id
      @uzid ||= self.transza.uzytkownik_id
      unless @uzid
        ##        logger.info "@@@@ #AkapitTranszy.get_uzid : @uzid is nil for @akat with id #{self.id}, assuming session[:uzid] (==#{session_uzid.inspect})" 
        @uzid = session_uzid
      end
    end

    return @uzid
  end

  def editable_par?( uzytkownik )
    if uzytkownik.kind_of?( Uzytkownik )
      u = uzytkownik
    else u = Uzytkownik.find( uzytkownik )
    end
    
    if u.id == self.get_uzid : return true
    else
      if u.rola_id == Rola.rid( :zarzadca ) : return true
      else return false
      end
    end
  end # of #{editable_par?}.

  
  def akat_hash
    unless @akat_hash
      @akat_hash =  { :akapit_transzy_id => self.id }.freeze
    end
    return @akat_hash
  end# of #{akat_hash}.


  def niezdezamb?
    # jeśli wszystko zdezambiguowane, zwrócimy #{nil}.
    # jeśli nie wszystko zdezamb, zwrócimy komunikat o~tym, które tokeny są niejednoznaczne
    niejed = ""
    self.akapit.token.collect { |tok153|
      dissize = tok153.disambs( self.akat_hash ).size
      if dissize != 1 : niejed.z_przecinkiem!( 
                                              "token &#0132;#{tok153.orth}&#0148; niezdezambiguowany" )
        @jednakze_mozna_zatwierdzic = false
      end  }# of token.collect |tok153|
    if niejed == "" : return nil
    else return niejed
    end
  end


  def niesensowny?
    nil
  end # of #niesensowny nie dla Eli



  def niefrazowny?(zdziw_sie = nil)
    niefraz = ""
    param = self.akat_hash
    # DlaEli  wszystkie tokeny nie-interp mają być we frazach
    # i ma być co najmniej jedna fraza werbalna.
    # dla AP nie mogą być wszystkie we frazach, bo nie ma frazy finitywnej.
    # Ale zdziwimy się, jeśli poza frazami więcej niż jeden.
    # 2008/02/29 wyłączamy zdziwienie u AP, gdy któryś token poza frazą.
    if DlaEli.x
      nie_we_frazie = 0
      self.akapit.token.each{ |tok165|
        fr = self.fraza(tok165.token_id)
        kg = tok165.disambs( self.akat_hash )[0].leksem.klasa_gram.klasa_gram_ozn
        if kg  != "interp" and kg != "qub" and not fr
          nie_we_frazie += 1
          if zdziw_sie
            niefraz.z_przecinkiem!(
                                   "token &#0132;#{tok165.orth}&#0148; jest poza frazą")
          end
        end
      }
    end

    #    unless DlaEli.x 
    #      niefraz = "" if (not zdziw_sie) or nie_we_frazie <= 1
    #    end
    
    # i każda fraza ma oznaczone co trzeba
    self.fraza_anot.each {|fraa|
      fraa_noti = (
                     if fraa.token_id_pocz == fraa.token_id_kon
                       "fraza &#0132;#{fraa.token_pocz.orth}&#0148; "
                     else
                       "fraza &#0132;#{fraa.token_pocz.orth} " +
                         if fraa.token_id_kon - fraa.token_id_pocz > 1 : "&#0151; " else "" end +
                         "#{fraa.token_kon.orth}&#0148; "
                     end )
      fraa_notice = fraa_noti + "nie ma "
      if (not fraa.token_id_pocz) or (not fraa.token_id_kon) or
          (not fraa.fraza_typ_id) 
        niefraz.z_przecinkiem!(fraa_notice + "typu")
        @jednakze_mozna_zatwierdzic = false
      else
        ft = fraa.fraza_typ
        if DlaEli.x and ft
          if ( ft.typ_symbol == "VP" and not (0..1).include?(fraa.vp_typ))
            niefraz.z_przecinkiem!( fraa_notice + "neg/pos")
            @jednakze_mozna_zatwierdzic = false
          end
          if ( ft.typ_symbol == "sie" and not FrazaAnot.sie_zakres.include?(fraa.sie_typ))
            niefraz.z_przecinkiem!( fraa_notice + "typu &#0132;się&#0148;")
            @jednakze_mozna_zatwierdzic = false
          end
        end # of if DlaEli
        
        if  (not fraa.token_id_synhead) 
          if ft.moze_bez_glowy?( :synh ) 
            niefraz.z_przecinkiem!(fraa_notice + "synh") if zdziw_sie
          else
            niefraz.z_przecinkiem!(fraa_notice + "synh")
            @jednakze_mozna_zatwierdzic = false
          end
        else # ma głowę nietypową lub niedopuszczalną
          synh = fraa.token_synhead
          dopg = ft.dopuszcza_glowe?( :synh, synh, param)
          if dopg
            if zdziw_sie
              niefraz.z_przecinkiem!(fraa_noti +
                                     "ma nietypową synh: &#0132;#{synh.orth}&#0148;") if dopg[0] == 0
            end
          else # nie dopuszcza takiej głowy
            niefraz.z_przecinkiem!(fraa_noti +
                                   "ma niedopuszczalną synh: &#0132;#{synh.orth}&#0148;")
            @jednakze_mozna_zatwierdzic = false
          end # of if dopg
        end # of ma / nie ma synh
        
        if  (not fraa.token_id_semhead) 
          if ft.moze_bez_glowy?( :semh ) 
            niefraz.z_przecinkiem!(fraa_notice + "semh") if zdziw_sie
          else
            niefraz.z_przecinkiem!(fraa_notice + "semh")
            @jednakze_mozna_zatwierdzic = false
          end
        else # ma semh nietypową lub niedopuszczalną
          semh = fraa.token_semhead
          dopg = ft.dopuszcza_glowe?( :semh, semh, param)
          if dopg
            if zdziw_sie
              niefraz.z_przecinkiem!(fraa_noti +
                                     "ma nietypową semh: &#0132;#{semh.orth}&#0148;") if dopg[0] == 0
            end
          else # nie dopuszcza takiej głowy
            niefraz.z_przecinkiem!(fraa_noti +
                                   "ma niedopuszczalną semh: &#0132;#{semh.orth}&#0148;")
            @jednakze_mozna_zatwierdzic = false
          end # of if dopg
        end # of nie ma semh
        fraa_notice.chomp!("nie ma ")
        # == "fraza ,,...---..” "
        
        # raczej ma byc jednoglowa 
        if fraa.token_id_synhead != fraa.token_id_semhead
          if ft.jednoglowa?
            niefraz.z_przecinkiem!( fraa_notice + "ma synh &#8800; semh" )
            @jednakze_mozna_zatwierdzic = false
          elsif ft.raczej_jednoglowa? and zdziw_sie
            # nie musi jednogłowa, ale ma ten sam pref. typ semh co synh
            niefraz.z_przecinkiem!( fraa_notice + "ma synh &#8800; semh" )
          end
        end # end of raczej jednogłowa 
      end # of czy nie ma typu i granic (else)
    } # of each fraa
    
    if DlaEli.x # dla Eli ma mieć frazę czasownikową (VP)
      ma_VP = ( self.fraza_anot.collect { |fraa|
                  if fraa.fraza_typ and fraa.fraza_typ.typ_symbol == "VP"
                    1;    else   nil;  end }.compact.size > 0)
      unless ma_VP
        niefraz.z_przecinkiem!("brak frazy czasownikowej") 
        @jednakze_mozna_zatwierdzic = false
      end
    end
    
    if niefraz == "" : return nil
    else return niefraz
    end

  end # of niefrazowny
  

    
    
  def self.znajdz( zdid, uzid )
    self.find(
              :first,
              :include => :transza,
              :conditions =>[
                             "akapit_transzy.akapit_id = ? and " +
                             " ( akapit_transzy.uzytkownik_id = ? or transza.uzytkownik_id = ?) ", 
                             zdid, uzid, uzid ])
  end# of self.znajdz
  
  
  def pocz_frazy?(tokid)
    pofra = nil
    self.fraza_anot(:refresh).each{ |fraa|
      pofra=fraa if fraa.token_id_pocz == tokid
    }
    return pofra
  end
  
  
  def reszta_frazy?(tokid)
    refra=nil
    self.fraza_anot(:refresh).each{ |fraa|
      refra = fraa if tokid > fraa.token_id_pocz and tokid <= fraa.token_id_kon
    }
    return refra
  end
  
  
  def we_frazie?( tokid )
    # jeśli token nr tokid nie jest w żadnej frazie tego akat, zwrócimy nil.
    # jeśli jest, to zwrócimy 0 gdy w środku, 1 na początku, 2 na końcu, 3 gdy stanowi całą frazę.
    wefra=nil
    if 1 == 0
      self.fraza_anot(:refresh).each{ |fraa|
        poczid = fraa.token_id_pocz
        konid = fraa.token_id_kon
        if (poczid..konid).include?(tokid)
          if tokid == poczid : wefra = 1
          else wefra = 0 end
          if tokid == konid : wefra += 2
          else wefra +=0 end
        end
      }
    end
    return wefra
  end # of #{we_frazie}

  def indeks_frazy(tokid)
    ifra= nil
    self.fraza_anot(:refresh).each{ |fraa|
      poczid = fraa.token_id_pocz
      konid = fraa.token_id_kon
      if (poczid..konid).include?(tokid)
        ifra = self.fraza_anot.index(fraa)
      end }
    return ifra
  end



  def fraza(tokid)
    fra = nil
    self.fraza_anot.each{ |fraa|
      fra = fraa if tokid >= fraa.token_id_pocz and tokid <= fraa.token_id_kon
    }
    return fra
  end
  
  
  ##  def blizniaczy
  ##    AkapitTranszy.find( self.blizniaczy_id )
  ##  end
  # załatwione przez self-referential #has_one.
  

  def weryfikacja( hasz = {} )
    # wołana przez #{\<anotacja_controller>.zweryfikuj_akapit}
    # zwraca hasz #**{:werdykt => \<$y$>, :werdykciki => {:\<poziom> => \<$x$> }, :\<poziom> => [\<id-y>]}*,
    #    gdzie $x==-1$ gdy weryfikacja dała na danym poziomie wynik niepomyślny,
    #      $x==0$ gdy akapit bliźniacze nie zatwierdzony na tym poziomie,
    #      $x == 1$ gdy wynik na danym poziomie pomyślny,
    #      $ y = \min(\{x_{\text{poziom}}\}_{\text{poziomy}} \cup\{1\}) $.
    ## dokonca = nil,
    ##      logger.info "@@@@ hasz do weryfikacji: #{hasz}"
    ##    logger.info "method #AkapitTranszy.weryfikacja od: #{hasz.inspect}"
    raise "#AkapitTranszy.weryfikacja:  :właśnie_zatwierdzamy is nil."    if hasz[ :właśnie_zatwierdzamy ] == nil
    protokoluj = hasz[:protokoluj]
    poziomy = [ hasz[:poziomy] ].flatten.compact
    
    rola_id = hasz[:rola_id]
    rola_id ||= Uzytkownik.find( self.get_uzid(hasz[:session_uzid]) ).rola_id

    ##    logger.info "               poziomy: #{poziomy.inspect}"

    if poziomy[0]
      weryf = {:werdykt => 1, :werdykciki => {} }
    else
      raise "#AkapitTranszy.weryfikacja: no annotation level given."
    end

    właśnie_zatw = hasz[:właśnie_zatwierdzamy]

    poziomy.each{ |poz|
      if protokoluj
        pr = Protokol.zrób_się( self.akapit, poz )
      else pr = nil
      end
      
      sb = self.bliźniaczy

      if (
          ( właśnie_zatw or self.ma_status?( poz, :>=, :zatwierdzony ) ) and
          ( sb.ma_status?( poz, :==, :zatwierdzony ) or
            sb.ma_status?( poz, :==, :po_poprawce ) or
            Rola.zarzadca?( rola_id ))
          ) or 
          ( hasz[ :dokonca ] and
            ( not właśnie_zatw ) and
            self.ma_status?( poz, :>=, :zatwierdzony ) and
            sb.ma_status?( poz, :>=, :zatwierdzony )
            )
        ##        logger.info "@@@@ rola_id: #{rola_id}, na poz. :#{poz}: mój statusek: #{self.statusek( poz )}, statusek bliźniaka  #{self.bliźniaczy.statusek( poz )}"
        ##        logger.info "@@@@ weryf_#{poz} #{Time.now}"
        self.send( "weryf_#{poz}", weryf, pr, protokoluj )
        ##        logger.info "@@@@ weryf_#{poz} #{Time.now}"
      elsif właśnie_zatw or hasz[ :dokonca ]
        weryf[ :werdykt ] = 0 if weryf[ :werdykt ] > 0
        weryf[ :werdykciki ][ poz ] = 0
      end
    }# of each #{poz}.

    primafalsa =  poziomy.collect{ |po| [ weryf[ po ] ] }.flatten.compact.min
    if primafalsa # jeśli mamy niezgodność, to umieścimy kotwiczkę trzy tokeny wyżej, żeby uwzględnić fixed header.
      self.akapit.set_primafalsa( weryf, primafalsa)
    end # of #{if primafalsa}
    
    ##    logger.info "@@@@@  weryf: " + weryf.inspect
    imple_superna_gratia( poziomy, weryf ) if właśnie_zatw
    return weryf
      
  end# of #{weryfikacja}.
  
  # Tu następują metody sprawdzenia gotowości i~weryfikacji akapit na poszczególnych poziomach anotacji.
  

  def segmentation_niegot?(  rola_id, zdziw_sie ) # zdziwienie nad sentences zależy od roli
    wynik =[]
    ##    wynik_orth = []
    self.sg_choice.each {|sgc|
      chosen_variant_met = false
      sgc.sg_variant.each{ |sgv|
        if sgvan = SgVariantAnot.find( :first, :conditions => 
                                       { :sg_variant_id => sgv.id,
                                         :akapit_transzy_id => self.id } )
          if chosen_variant_met 
            if sgvan.chosen?
              sgv.token.each{ |tok154| wynik << [ tok154.id, tok154.orth ]
              }
            end
          else chosen_variant_met =  sgvan.chosen?
          end   
        else
          sgv.token.each{ |tok155| wynik << [ tok155.id, tok155.orth ] }
        end
      }# of each variant
      unless chosen_variant_met
        sgc.token.each{ |tok156| wynik << [ tok156.id, tok156.orth ] }
      end
    }# of each choice
    
    wynik.uniq!
    wynik, wynik_orth = wynik.dx, wynik.dy

    if wynik[0]
      return "Nie mogę zatwierdzić akapitu, w którym token(y) #{wynik_orth.join(', ')} ma(ją) nie ujednoznacznioną segmentację."
    else return ''
    end
  end # of #{segmentation_niegot?}.

  
  def wyniknij( poziom, weryf, wynik, werdykcik )
    wynik = nil unless wynik[0]
    weryf[:werdykt] = werdykcik if weryf[:werdykt] > werdykcik
    weryf[:werdykciki][poziom] = werdykcik
    weryf[poziom] = wynik if wynik
  end # of #{wyniknij}.
  
  
  def weryf_segmentation( weryf, pr, protokoluj )
    ##      logger.info "@@@ weryf_segmentation"
    wynik = []
    werdykcik = 1
    
    self.sg_choice.each {|sgc|
      sgc.sg_variant.each{ |sgv|
        currverd = nil
        sgvans = sgv.sg_variant_anot
        if ( sgvans.size == 2 ) and ( sgvans[ 0 ].chosen? != sgvans[ 1 ].chosen? )
          sgv.token.each{ |tok157| wynik << tok157.id }
          currverd = -1 

        elsif sgvans.size != 2 # weryfikujemy, a~więc akapit został sprawdzony, że po naszej stronie ma wszystko zaanotowane. Zakładam, że jak nie 2, to 1.
          currverd = -1  # jeżeli akapit bliźniaczy ma status c.n. #{:zatwierdzony}, a~ta segmentacja nie ma pary, to coś jest nie halo.
          sgv.token.each{ |tok158|  wynik << tok158.id }
        end

        if currverd == -1 and protokoluj
          pr.protokoluj_segmentation( self, sgc, sgv )
          pr.protokoluj_segmentation( self.bliźniaczy, sgc, sgv )
        end

        werdykcik = currverd   if werdykcik > -1 and currverd == -1
      }# of each variant
    }# of each choice      
    
    self.wyniknij( :segmentation, weryf, wynik, werdykcik )
    
  end# of #{weryf_segmentation}.
  
  
  def ujednoznacznij_segmentacje
    tokens = self.akapit.token
    tokids = tokens.collect {|tok159| tok159.id}
    self.segmentacja_anot.each{ |sa|
      # przejrzymy tokeny, przestawimy im # czy_segm na # false,
      # a~te, które należy połączyć, najpierw zaprotokołujemy, jakie były, a~potem połączymy.
      i = tokids.index( sa.token_id )
      token_nast = tokens[ i+1 ]
    }
  end # of # ujednoznacznij_segmentacje
  
  
  def zdziwko( zdziw_sie, komunikat )
    if komunikat == '' or komunikat == nil
      return ''
    else
      if  zdziw_sie and @jednakze_mozna_zatwierdzic
        return "Dziwię się, że "+ komunikat + "."
      else
        return "Nie mogę zatwierdzić akapitu, w którym " + komunikat + "!" 
      end
    end
  end  # of #{zdziwko}.
  

  def sentences_niegot?( rola_id, zdziw_sie=nil )
    # zdziwimy się, jeśli znak interpunkcyjny, który zwykle kończy zdanie, nie jest oznaczony jako taki, oraz jeśli ostatni token akapitu nie kończy zdania.
    komunikat = []
    if zdziw_sie and not Rola.zarzadca?( rola_id )
      wynik = []
      wynik_orth = []
      self.akapit.chosen_interps.each{ |interp|
        if ['.', '?', '!'].include?( interp.orth ) and not KoniecZdaniaAnot.znajdz( self, interp )
          wynik << interp.id
          wynik_orth << "[#{if ipo = interp.poprzedni : ipo.orth end}]" + interp.orth
        end
      }
      if wynik[0]
        komunikat << "Dziwię się, że token(y) #{wynik_orth.join(' ')} nie kończy/ą zdania."
      end
    end

    if not self.koniec_zdania_anot[0]
      komunikat <<  "Nie mogę zatwierdzić akapitu, w którym nie oznaczono ani jednego końca zdania."
    end

    return komunikat.join(' ')

  end # of #{sentences_niegot?}
  

  def  weryf_sentences( weryf, pr, protokoluj )
    wynik = []
    werdykcik = 1
    
    self.akapit.token.each{ |t160|
      currverd = nil
      unless [0,2].include?( t160.koniec_zdania_anot.size )
        currverd = -1
        wynik << t160.id
      end
    
      if currverd == -1 and protokoluj
        pr.protokoluj_sentences( self, t160 )
        pr.protokoluj_sentences( self.bliźniaczy, t160 )
      end
      
      werdykcik = -1 if currverd == -1 and werdykcik > -1
    }
    
    self.wyniknij( :sentences, weryf, wynik, werdykcik )
  end
  
  def morphosyntactic_niegot?( rola_id, zdziw_sie=nil )
    self.zdziwko( zdziw_sie,  self.niezdezamb? )
  end # of #{morphosyntactic_niegot?}.
  
  
  def weryf_morphosyntactic( weryf, pr, protokoluj )
    # sprawdzamy tokeny: dyzambiguacje i sensy
    wynik = []
    werdykcik = 1
    akat = self
    akath = self.akat_hash
    bliakat = self.bliźniaczy
    bliakath = bliakat.akat_hash

    loggi = {}
    poprz, nast = Time.now, Time.now
    logujcz = Proc.new {|w, t|
      loggi[ w ] ||= 0.0
      poprz, nast =nast, Time.now
      loggi[w] += nast - poprz
      ##      logger.info "@@@ #{t.id} #{w}: #{nast - poprz} "
    }

    self.akapit.token.each {|tok161|
      currverd = nil
                                           logujcz.call( :pocz, tok161 )
      disa = tok161.disambs( akath )[0]
      blidisa = tok161.disambs( bliakath )[0]
      # dyzambiguacje są jednoznaczne, skoro akapit zatwierdzony+.
                                         logujcz.call( :po_znajdź_disa, tok161 )
      unless disa and blidisa 
        wynik << tok161.id
        currverd = -1 
        # weryfikujemy, a~więc jeśli w~bliźniaczym brakuje którejś dezambiguacji, to znaczy, że nie jest dokończony. A~jednak ma statusek c.n. zatwierdzony, czyli coś nie halo.
                                             logujcz.call( :nie_ma_disa )      
      else # są #disa i~#{blidisa}
#        diclass << disa.class
#        diclass << blidisa.class
 

        if (disa.leksem_id != blidisa.leksem_id) or (disa.reszta_tagu != blidisa.reszta_tagu)
          currverd = -1
          wynik << tok161.id
        end
      end
      
      if currverd == -1 and protokoluj
        pr.protokoluj_morphosyntactic( akat, tok161, disa ) 
        pr.protokoluj_morphosyntactic( bliakat, tok161, blidisa )
      end

      werdykcik = -1 if currverd == -1 and werdykcik > -1

    } # of #{each token}.

    logger.info "@@@ weryf_morphosyntactic #{loggi.inspect}"    
    ##  logger.info " (bli)disa.class: #{diclass.uniq.inspect}"
    logger.info "@@@ weryf_morphosyntactic przed wyniknij: #{Time.now}"    
    wyniknij( :morphosyntactic, weryf, wynik, werdykcik )

  end# of #{weryf_morphosyntactic}.


  def word_senses_niegot?(  rola_id, zdziw_sie ) # zdziwienie nad sentences zależy od roli
    wynik =[]
    ##    wynik_orth = []
    wszystkie_tokeny_osensowane = true
    self.akapit.token.each { |tok188|
      if tok188.do_sensu?( self.akat_hash ) and not tok188.the_sens( self.akat_hash )
        wynik << [ tok188.id, tok188.orth ]
      end}

    wynik, wynik_orth = wynik.dx, wynik.dy

    if wynik[0]
      return "Nie mogę zatwierdzić akapitu, w którym nie wskazano sensu tokenu(ów) #{wynik_orth.join(', ')}."
    else return ''
    end
  end # of #{word_senses_niegot?}.


  def weryf_word_senses( weryf, pr, protokoluj )
    ##      logger.info "@@@ weryf_segmentation"
    wynik = []
    werdykcik = 1
    
    self.akapit.token.each {|tok189|
      currverd = nil
      if tok189.do_sensu?( self.akat_hash ) or tok189.do_sensu?( self.bliźniaczy.akat_hash )
        # Korzystamy z tego, że \ac{WSD} są następnikiem \ac{MS}, wobec czego obie interpretacje morfosyntaktyczne każdego tokenu są zgodne i nie musimy tego sprawdzać.
        if ( the_sens189a = tok189.the_sens( self.akat_hash )) !=
            ( the_sens189b = tok189.the_sens( self.bliźniaczy.akat_hash ))
          # zresztą, gdyby nie były zgodne, to ich #{the_sens}y będą się różnić.
          wynik << tok189.id
          currverd = -1
        end
      end
      
      if currverd == -1 and protokoluj
        pr.protokoluj_word_senses( self, tok189, the_sens189a )
        pr.protokoluj_segmentation( self.bliźniaczy, tok189, the_sens189b )
      end
      
      werdykcik = currverd   if werdykcik > -1 and currverd == -1
    }
    
      self.wyniknij( :word_senses, weryf, wynik, werdykcik )
    
  end# of #{weryf_segmentation}.
  

  
  def self.status_betw( status )
    # dopuszczalne wartości: symbole statusów: #{:nie_dopuszczony}, #{:dopuszczony} itd. oraz #{:zakończony} (l.p.) #{:anotaśne}, #{oczekujące} (l.mn.), bo chodzi o mnogą liczbę \emph{statusów}.
    if status == :whatever
      betw = " not null "
    elsif status == :anotaśne
      betw = " in (#{STATI[:anotaśne].join(', ')}) "
    elsif status == :oczekujące
      betw = " in (#{STATI[:oczekujące].join(', ')}) "
    else
      status1, status2 = status1_2( status )
      if (status2 - status1) % 1000 == 0
        betw = " > #{status1 - 1} "
      else
        betw = " between #{status1} and #{status2} "
      end
    end
    betw
  end # of #{self.status_betw}


  def self.ile_zaanotowanych( id=nil, status=:zakończony, format=:inspect )

    betw = self.status_betw( status )
    
    if 1==1 # selecty sprawdzone jako działające
      szkatulki = @@poziomy_działające.collect{ |poz|
        " sum( case when s.#{poz} " + betw +
        " then 1 else 0 end ) as #{poz}"}.join(", ")
      
      if id
        
        if  id.kind_of?( Integer ) or ( uzid = id[ :uzid ] )
          uzid ||= id
          transza_clause, transza_id = '', nil
          esquelle = 
            Proc.new {|poz| [  "select count(*) as ile from statusy s inner join " +
                               " transza t using( transza_id ) " +
                               " where  #{poz}" + betw +
                               " and (s.#{poz}_uzid = ? or ( s.#{poz}_uzid is null and t.uzytkownik_id=?)) ",
                               uzid, uzid ] }
        else 
          transza_id = id[:transza_id]
          esquelle =
            Proc.new {|poz| [  "select count(*) as ile from statusy  " +
                               " where  #{poz}" + betw +
                               ' and transza_id in (?) ', transza_id ] }
        end
        ilezaa = @@poziomy_działające.collect{ |poz|
          self.find_by_sql( esquelle.call( poz ) )[0].ile.to_i
        }
      else # not #uzid
        rekord = self.find_by_sql( "select " + szkatulki + " from statusy s " )[0]
        ilezaa = @@poziomy_działające.collect{ |poz|
          rekord.send( poz ).to_i/2
        }
      end

    else # not #{1==1} — alternatywne selecty, najprawdopodobniej równie dobre.
      
      if uzid
        ilezaa = @@poziomy_działające.collect{ |poz| 
          self.find_by_sql([ "select count(*) as ile from akapit_transzy akat " +
                             " inner join statusy s on akat.akapit_transzy_id=s.akapit_transzy_id " +
                             " where s.#{poz} #{betw} and akat.uzytkownik_id = ? ", uzid ])[0].ile.to_i
        }
      else
        ilezaa = @@poziomy_działające.collect{ |poz| 
          self.find_by_sql( "select count(*) as ile from  statusy s " +
                            " where s.#{poz} #{betw} " )[0].ile.to_i/2
        }
      end
    end
    return ilezaa.send( format )                       
  end# of #{self.ile_zaanotowanych}.


  def self.ile_zaanotowanych_total( uzid=nil, status=:zakończony )
    betw = self.status_betw( status )
       
    unless uzid
      kriterion = @@poziomy_działające.collect{ |poz|
        " ( s.#{poz} #{betw} ) " }.
        join(" or ")
      
      sql =  "select count(*) as ile from statusy s where " + kriterion
    
    else # when #uzid is given
      kriterion = @@poziomy_działające.collect{ |poz|
        " ( s.#{poz} #{betw} and ( s.#{poz}_uzid=? or t.uzytkownik_id=? )) " }.
        join(" or ")
      sql = [ "select count(*) as ile from statusy s inner join " +
              " transza t using( transza_id ) where " + kriterion ]
      (@@poziomy_działające.size *2).times{ |i|
        sql << uzid
      }
    end # of if uzid or not
        
    ##    logger.info "@@@@@ " + sql.inspect
    
    ilezaa = self.find_by_sql( sql )[0].ile.to_i

    ilezaa /= 2    if status == :podsądny

    ilezaa.to_s
    # to ma być string
        
  end # of #{self.ile_zaanotowanych_total}




  def statuski
    self.statusy.statuski
  end # of #{statuski}


  def set_status( poziom, status_symbol, tylko_to=false, uzid=nil )
    # dołączamy czwarty, opcjonalny parametr #{uzid}, żeby można było zadać id użytkownika przy automatycznym ujednoznacznieniu segmentacji.
    # Na koniec patrzymy, czy przypadkiem nie zmienia się „duży status”, tj. pole \sql{status} w~rekordzie \sql{akapit_transzy} — które ma być równe najmniejszemu statuskowi.
    # tu nie powinno być transakcji: jest wołane już w~jakiejś transakcji.
    logger.info "@@@ set_status \"akat\"=>\"#{self.id}\": poziom #{poziom.inspect}, ssym #{status_symbol.inspect} tylko_to #{tylko_to.inspect} uzid #{uzid.inspect}"
    akat = self
    bliakat = akat.bliźniaczy
    akats=self.statusy
    bliakats = bliakat.statusy
    akats.set_poziom( poziom,  status_symbol, :bez_uS ) # w tym jest #{propaguj_dopuszczalność}.
    bliakats.set_poziom( poziom, status_symbol, :bez_uS ) unless tylko_to
    if status_symbol == :zweryfikowany or
        ( (not akats.uzid( poziom )) and status_symbol == :osądzony )
      # test sprawdza tylko #{akat}, a nie #{bliakat}, ale dzięki transakcji
      # możemy zakładać, że #{not akat.uzytkownik_id} wtw #{not bliakat.uzytkownik_id}
      if uzid : bluzid = uzid
      else bluzid=nil
      end
      uzid ||= akat.transza.uzytkownik_id
      akats.set_uzid( poziom , uzid )
      unless tylko_to
        bluzid ||=  bliakat.transza.uzytkownik_id
        bliakats.reload.set_uzid( poziom,  bluzid )
      end
    end
    akats.save!
    bliakats.save! unless tylko_to
    
    akat.update_Status( akats )
    bliakat.update_Status( bliakats ) unless tylko_to
  end # of # {set_status}.
  
  def update_Status( akats=nil )
    # Chcemy, by niezmiennikiem bazy danych było, że w~kolumnie \sql{status} tabeli \sql{akapit_transzy} znajduje się najmniejszy ze statusków danego akapitu transzy.
    ## logger.info "@@@@ update_Status pre: akat #{self.id}: #{self.statuski.inspect} --> #{self.status}"
    # 2009/7/8 mój umysł otworzył się i~osiągnąłem oświecenie: zmartwiłem się bowiem, że ustalanie Statusu ze statusków trzeba uzależnić od konkretnych poziomów, czy są one niezależne czy zależne. Otóż nie trzeba: to dopuszczacz kolejnych poziomów do anotacji dba o~to, by anotacja na wyższym stała się możliwa dopiero po zaanotowaniu na niższym. To zatem, że na jakimś poziomie jest »zatw«, a~na innym »osądzany«, oznacza, że według dopuszczacza poziomy te są niezależne — i~#update_Status nie musi tego sprawdzać.

    akats ||= self.statusy( :refresh )
    akatss = akats.statuski
    statuski_anot = akatss & ((0...16).to_a) # przecinamy statuski z~przedziałem [#{:dopuszczony}, #{:zweryfikowany})
    duzy_Status = statuski_anot.min # było max, 2009/04/10 zmieniłem na min zwna nieliniowość porządku poziomów.
    dS_popr = akatss & ((10..12).to_a)
    duzy_Status =  dS_popr.min   if dS_popr[0]

    duzy_Status ||= akatss.max # jeśli na wszystkich poziomach jest c.n. zweryfikowany, to zwracamy tę wartość.
    ##    logger.info "@@@@ self.status: #{self.status.inspect}, duzy_Status: #{duzy_Status.inspect}"
    if self.status != duzy_Status or true # 2009/02/27 okazało się, że są różne, a jednak się nie zapisuje.
      self.status = duzy_Status
      self.save!
      ## logger.info "@@@@ update_Status of akapit transzy #{self.id}"
    end
    logger.info "@@@@ update_Status post: \"akat\"=>\"#{self.id}\": #{self.statusy.reload.statuski.inspect} --> #{self.reload.status}, bliźniak: #{self.bliźniaczy.statusy.reload.statuski.inspect} --> #{self.bliźniaczy.reload.status}"

  end # of #{update_Status}.
  

  def self.update_all_Stati( akapit_od=0, akapit_do=10000000000 )
    Statusy.dopuść_minimalne
    self.find_all.each{ |akat| akat.update_Status
      puts "#{akat.id}: #{akat.status}"}
    return true
  end # of #{self.update_all_Stati}.
  
  def status_co_najmniej=( poziom, status_symbol )
    # uwaga! ona nie zapisuje akat.statusy!
    akats = self.statusy
    akats.set_poziom( poziom,
                    [[ STATI[status_symbol].to_i, 
                       akats.send( poziom )].max , STATI[:osądzany]].min )
    # W jednym wypadku zmieniamy także status akapit bliźniaczego: kiedy były oba zweryfikowane.
    blis = self.bliźniaczy.statusy
    if blis.send( poziom ) == STATI[:zweryfikowany]
      blis.set_poziom( poziom, STATI[:osądzany] )
      blis.save
    end
  end# of #status_co_najmniej=
  
  
  def propaguj_dopuszczalność( poziom )
    self.statusy.propaguj_dopuszczalność( poziom )
  end# of #propaguj_dopuszczalność
  
  
  def komentarz( uzid = nil, czy_tylko_nowe = nil )
    if uzid :  conds_hash = {
        :uzytkownik_id => uzid,
        :akapit_id => self.akapit_id }
      
    else conds_hash = {:akapit_id => self.akapit_id}
    end # of if uzid
    
    conds_hash.update( { :nowy => true } ) if czy_tylko_nowe

    Komentarz.find(:all, :conditions => conds_hash, :order => :created_at  )
  end # of komentarz
  
  
  def skopiuj_na_bliźniaczy( session_uzid,  *poziomy )
    # nie obudowujemy tego transakcją tutaj, bo tę metodę będziemy wołali w transakcji 
    # w # \<anotacja_controller>.zatwierdz_akapit
    
    akat = self
    @bliakat = akat.bliźniaczy
    @uzid = akat.get_uzid( session_uzid )
    @bluzid = @bliakat.get_uzid( session_uzid )
    @akath = akat.akat_hash
    @bliakath = @bliakat.akat_hash

    @bliakat.odrzucony = akat.odrzucony
    # przy osądzeniu akapit przypiszemy bliźniaczemu jego prawnego anotatora, 
    # ale to w~momencie ustalania statusu.
    
    poziomy.each{ |poz| self.send( "skopiuj_#{poz}" ) 
      akat.statusy.set_uzid( poz, @uzid )
      @bliakat.statusy.set_uzid( poz, @bluzid )
    }
        
    # zapisz bliźniacze
    @bliakat.save!
    logger.info "@@@@ skopiuj na bliźniaczy wykonano, *poziomy: #{poziomy.inspect}"
  end # of #{skopiuj_na_bliźniaczy}.
  
    
  def skopiuj_segmentation
    @bliakat.sg_variant_anot.delete_all
    self.sg_variant_anot.each{ |sgva|
      @bliakat.sg_variant_anot.create(
                                      :sg_choice_id => sgva.sg_choice_id,
                                      :sg_variant_id => sgva.sg_variant_id,
                                      :chosen => sgva.chosen,
                                      :akapit_transzy_id => @bliakat,
                                      :uzytkownik_id => @bluzid )
    }
  end # of #{skopiuj_segmentation}.
  
  
  def skopiuj_sentences
    @bliakat.koniec_zdania_anot.delete_all
    self.koniec_zdania_anot.each{ |kz|
      @bliakat.koniec_zdania_anot.create(
                                         :akapit_id => kz.akapit_id,
                                         :akapit_transzy_id => @bliakat,
                                         :uzytkownik_id => @bluzid,
                                         :token_id => kz.token_id
                                         )
    }
  end# of #{skopiuj_sentences}

  
  def skopiuj_morphosyntactic
    @bliakat.interpretacja_anot.delete_all
    self.interpretacja_anot.each{ |ia|
      @bliakat.interpretacja_anot.create(
                                         :uzytkownik_id => @bluzid,
                                         :token_id => ia.token_id,
                                         :interpretacja_id => ia.interpretacja_id
                                         )
    }
  end # of #{skopiuj_morphosyntactic}.

  
  # Metody wykonujące dodatkowe operacje gdy zdanie zostało zweryfikowane na odp. poziomie. %$$$$$$$
  
  def commit_segmentation
    # oznaczamy akapit jako ujednoznaczniony segmentacyjnie (co znaczy, że został wybrany wariant segmentacji oraz zostały określone granice zdań).
    # zakładam, że wołamy tę metodę z~miejsca, w~którym już wiemy, że decyzje segmentacyjne obojga Anotatorów są zgodne. Bierzemy więc ten (którykolwiek) \<akapit_transzy>  i~przeglądamy jego \<sg_variant_anot>
    
    # ujednoznacznienie segmentacji:
    # mamy dla każdego tokenu mającego wariant segmentacji mamy anotowany wariant segmentacji.
    ( sa196 = self.akapit ).token_segm.each{ |tok162| 
      unless tok162.sg_variant_anot( self.akat_hash ).chosen?
        tok162.chosen = false 
        tok162.chosen_updated_at = Time.now
        tok162.save!
      end
      # wszystkie inne tokeny mają #{.chosen == true }.
    }# of each token
    
    sa196.update_treści
    
  end# of #{commit_segmentation}.
  

  def commit_sentences
    ( sa196 = self.akapit ).token.each{ |tok163|
      tok163.czy_konczy_zdanie = (
                                  if tok163.koniec_zdania_anot[ 0 ] : true
                                  else false        
                                  end )
      tok163.czy_konczy_zdanie_updated_at = Time.now
      tok163.save!
    }
    
    sa196.update_treści
  end # of #{commit_sentences}.

  
  def commit_morphosyntactic
    # w każdym tokenie oznaczamy interpretację wybraną zgodnie przez obie anotatorki jako dezambiguację
    self.interpretacja_anot.each{ |ia|
      iai =  ia.interpretacja
      iai.disamb  = true
      iai.save!
    }
  end# of #{commit_morphosyntactic}.
    
  def commit_word_senses
    ##    raise "musimy doliczyć sensy zweryfikowane"
    ## self.sens_anot.each { |sa190|
    # Nie jestem pewien, czy sens należy twardo notować w tabeli interpretacja. Chyba nie.
    ##    }
  end# of #{commit_word_senses}


  def anotatorka( poziom )
    if uzid = self.statusy.send( "#{poziom}_uzid" )
      Uzytkownik.find( uzid ) 
    end
  end # of # anotatorka

  def primus_sensibilis
    # uwaga! to działa wyłącznie po weryfikacji na poziomie \ac{MS}.
    self.akapit.primus_sensibilis
  end

  
  def self.count_diai
    self.count_by_sql( "select count( distinct akapit_id ) as ile from akapit_transzy" )
  end
  

  ## def self.unnull_akat_bliźniaki
  ##  end
  # jest w \file{ramkowanie.rb} jako metoda klasy #{ActiveRecord::Base}.

  def autozatwierdź_word_senses
    self.statusy.autozatwierdź_word_senses
  end
 

  private

  def imple_superna_gratia( poziomy, weryf )
    # Jeżeli stwierdziliśmy rozbieżności, to wyryjemy je w~granicie kolumny \sql{superancja} tabeli \sql{token}
    # #weryf jest weryfikacją akapitu.
    # metodę tę wołamy wyłącznie w~jednym miejscu: na koniec #{weryfikacja}.
    # 2009/7/10 a~jeśli stwierdzimy brak rozbieżności, to zakleimy to, cośmy wyryli dawniej.
    tok_su = self.akapit.token_sup
    poziomy.each {|poz|
      # zaznaczymy rozbieżności
      if weryf[ :werdykciki ][ poz ] == -1
        Token.find( weryf[ poz ] ).each { |tok164|
          tok164.superancja ||= []
          tok164.superancja |= [ poz ]
          tok164.save!
        } # of each token
      end # of if werdykcik -1
      # odznaczymy zgodności, ale tylko jeśli oba akaty są po poprawce
      if [self.statusy.send( poz ), self.bliźniaczy.statusy.send( poz )].uniq == [STATI[:po_poprawce]]
        logger.info "@@@@ odżółcam akat #{self.id} #{Time.now.to_s( :db )}"
        rozbidy = [weryf[poz]].flatten.compact
        tok_su.each { |tsu|
          unless rozbidy.include?( tsu.id )
            tsu.odżółć( poz )
          end
        }
      end # of if oba po poprawce
    }
  end # of #{imple_superna_gratia}


  # #dopuść_wsd jest metodą klasy #{Statusy}, odpalaną przy jej inicjacji.

 
end # of class.

### Local Variables: 
### mode: ruby
### End:
