text:
<?php

/**
 * Base class that represents a row from the 'photo' table.
 *
 *
 *
 * This class was autogenerated by Propel 1.4.2
 *
 *
 * @package    lib.model.om
 */
abstract class BasePhoto extends BaseObject  implements Persistent {

	/**
	 * The Peer class.
	 * Instance provides a convenient way of calling static methods on a class
	 * that calling code may not be able to identify.
	 * @var        PhotoPeer
	 */
	protected static $peer;

	/**
	 * The value for the id field.
	 * @var        int
	 */
	protected $id;

	/**
	 * The value for the photoalbum_id field.
	 * @var        int
	 */
	protected $photoalbum_id;

	/**
	 * The value for the created_at field.
	 * @var        string
	 */
	protected $created_at;

	/**
	 * The value for the updated_at field.
	 * @var        string
	 */
	protected $updated_at;

	/**
	 * The value for the show field.
	 * Note: this column has a database default value of: true
	 * @var        boolean
	 */
	protected $show;

	/**
	 * The value for the order field.
	 * @var        int
	 */
	protected $order;

	/**
	 * The value for the img field.
	 * @var        string
	 */
	protected $img;

	/**
	 * The value for the full_path field.
	 * @var        string
	 */
	protected $full_path;

	/**
	 * The value for the preview_path field.
	 * @var        string
	 */
	protected $preview_path;

	/**
	 * The value for the thumb_path field.
	 * @var        string
	 */
	protected $thumb_path;

	/**
	 * The value for the link field.
	 * @var        string
	 */
	protected $link;

	/**
	 * The value for the width field.
	 * @var        int
	 */
	protected $width;

	/**
	 * The value for the height field.
	 * @var        int
	 */
	protected $height;

	/**
	 * The value for the carousel field.
	 * Note: this column has a database default value of: false
	 * @var        boolean
	 */
	protected $carousel;

	/**
	 * @var        Photoalbum
	 */
	protected $aPhotoalbum;

	/**
	 * @var        array PhotoI18n[] Collection to store aggregation of PhotoI18n objects.
	 */
	protected $collPhotoI18ns;

	/**
	 * @var        Criteria The criteria used to select the current contents of collPhotoI18ns.
	 */
	private $lastPhotoI18nCriteria = null;

	/**
	 * Flag to prevent endless save loop, if this object is referenced
	 * by another object which falls in this transaction.
	 * @var        boolean
	 */
	protected $alreadyInSave = false;

	/**
	 * Flag to prevent endless validation loop, if this object is referenced
	 * by another object which falls in this transaction.
	 * @var        boolean
	 */
	protected $alreadyInValidation = false;

	// symfony behavior

	const PEER = 'PhotoPeer';

	// symfony_i18n behavior

	/**
	 * @var string The value for the culture field
	 */
	protected $culture = null;

	/**
	 * @var array Current I18N objects
	 */
	protected $current_i18n = array();

	/**
	 * Applies default values to this object.
	 * This method should be called from the object's constructor (or
	 * equivalent initialization method).
	 * @see        __construct()
	 */
	public function applyDefaultValues()
	{
		$this->show = true;
		$this->carousel = false;
	}

	/**
	 * Initializes internal state of BasePhoto object.
	 * @see        applyDefaults()
	 */
	public function __construct()
	{
		parent::__construct();
		$this->applyDefaultValues();
	}

	/**
	 * Get the [id] column value.
	 *
	 * @return     int
	 */
	public function getId()
	{
		return $this->id;
	}

	/**
	 * Get the [photoalbum_id] column value.
	 *
	 * @return     int
	 */
	public function getPhotoalbumId()
	{
		return $this->photoalbum_id;
	}

	/**
	 * Get the [optionally formatted] temporal [created_at] column value.
	 *
	 *
	 * @param      string $format The date/time format string (either date()-style or strftime()-style).
	 *							If format is NULL, then the raw DateTime object will be returned.
	 * @return     mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00
	 * @throws     PropelException - if unable to parse/validate the date/time value.
	 */
	public function getCreatedAt($format = 'Y-m-d H:i:s')
	{
		if ($this->created_at === null) {
			return null;
		}

		if ($this->created_at === '0000-00-00 00:00:00') {
			// while technically this is not a default value of NULL,
			// this seems to be closest in meaning.
			return null;
		} else {
			try {
				$dt = new DateTime($this->created_at);
			} catch (Exception $x) {
				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->created_at, true), $x);
			}
		}

		if ($format === null) {
			// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
			return $dt;
		} elseif (strpos($format, '%') !== false) {
			return strftime($format, $dt->format('U'));
		} else {
			return $dt->format($format);
		}
	}

	/**
	 * Get the [optionally formatted] temporal [updated_at] column value.
	 *
	 *
	 * @param      string $format The date/time format string (either date()-style or strftime()-style).
	 *							If format is NULL, then the raw DateTime object will be returned.
	 * @return     mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00
	 * @throws     PropelException - if unable to parse/validate the date/time value.
	 */
	public function getUpdatedAt($format = 'Y-m-d H:i:s')
	{
		if ($this->updated_at === null) {
			return null;
		}

		if ($this->updated_at === '0000-00-00 00:00:00') {
			// while technically this is not a default value of NULL,
			// this seems to be closest in meaning.
			return null;
		} else {
			try {
				$dt = new DateTime($this->updated_at);
			} catch (Exception $x) {
				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->updated_at, true), $x);
			}
		}

		if ($format === null) {
			// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
			return $dt;
		} elseif (strpos($format, '%') !== false) {
			return strftime($format, $dt->format('U'));
		} else {
			return $dt->format($format);
		}
	}

	/**
	 * Get the [show] column value.
	 *
	 * @return     boolean
	 */
	public function getShow()
	{
		return $this->show;
	}

	/**
	 * Get the [order] column value.
	 *
	 * @return     int
	 */
	public function getOrder()
	{
		return $this->order;
	}

	/**
	 * Get the [img] column value.
	 *
	 * @return     string
	 */
	public function getImg()
	{
		return $this->img;
	}

	/**
	 * Get the [full_path] column value.
	 *
	 * @return     string
	 */
	public function getFullPath()
	{
		return $this->full_path;
	}

	/**
	 * Get the [preview_path] column value.
	 *
	 * @return     string
	 */
	public function getPreviewPath()
	{
		return $this->preview_path;
	}

	/**
	 * Get the [thumb_path] column value.
	 *
	 * @return     string
	 */
	public function getThumbPath()
	{
		return $this->thumb_path;
	}

	/**
	 * Get the [link] column value.
	 *
	 * @return     string
	 */
	public function getLink()
	{
		return $this->link;
	}

	/**
	 * Get the [width] column value.
	 *
	 * @return     int
	 */
	public function getWidth()
	{
		return $this->width;
	}

	/**
	 * Get the [height] column value.
	 *
	 * @return     int
	 */
	public function getHeight()
	{
		return $this->height;
	}

	/**
	 * Get the [carousel] column value.
	 *
	 * @return     boolean
	 */
	public function getCarousel()
	{
		return $this->carousel;
	}

	/**
	 * Set the value of [id] column.
	 *
	 * @param      int $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setId($v)
	{
		if ($v !== null) {
			$v = (int) $v;
		}

		if ($this->id !== $v) {
			if ($this->id === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::ID;
			}
			$this->id = $v;
		}

		return $this;
	} // setId()

	/**
	 * Set the value of [photoalbum_id] column.
	 *
	 * @param      int $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setPhotoalbumId($v)
	{
		if ($v !== null) {
			$v = (int) $v;
		}

		if ($this->photoalbum_id !== $v) {
			if ($this->photoalbum_id === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::PHOTOALBUM_ID;
			}
			$this->photoalbum_id = $v;
		}

		if ($this->aPhotoalbum !== null && $this->aPhotoalbum->getId() !== $v) {
			$this->aPhotoalbum = null;
		}

		return $this;
	} // setPhotoalbumId()

	/**
	 * Sets the value of [created_at] column to a normalized version of the date/time value specified.
	 *
	 * @param      mixed $v string, integer (timestamp), or DateTime value.  Empty string will
	 *						be treated as NULL for temporal objects.
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setCreatedAt($v)
	{
		// we treat '' as NULL for temporal objects because DateTime('') == DateTime('now')
		// -- which is unexpected, to say the least.
		if ($v === null || $v === '') {
			$dt = null;
		} elseif ($v instanceof DateTime) {
			$dt = $v;
		} else {
			// some string/numeric value passed; we normalize that so that we can
			// validate it.
			try {
				if (is_numeric($v)) { // if it's a unix timestamp
					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
					// We have to explicitly specify and then change the time zone because of a
					// DateTime bug: http://bugs.php.net/bug.php?id=43003
					$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
				} else {
					$dt = new DateTime($v);
				}
			} catch (Exception $x) {
				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
			}
		}

		if ( $this->created_at !== null || $dt !== null ) {
			// (nested ifs are a little easier to read in this case)

			$currNorm = ($this->created_at !== null && $tmpDt = new DateTime($this->created_at)) ? $tmpDt->format('Y-m-d H:i:s') : null;
			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;

			if ( ($currNorm !== $newNorm) // normalized values don't match
					)
			{
				$this->created_at = ($dt ? $dt->format('Y-m-d H:i:s') : null);
				$this->modifiedColumns[] = PhotoPeer::CREATED_AT;
			}
		} // if either are not null

		return $this;
	} // setCreatedAt()

	/**
	 * Sets the value of [updated_at] column to a normalized version of the date/time value specified.
	 *
	 * @param      mixed $v string, integer (timestamp), or DateTime value.  Empty string will
	 *						be treated as NULL for temporal objects.
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setUpdatedAt($v)
	{
		// we treat '' as NULL for temporal objects because DateTime('') == DateTime('now')
		// -- which is unexpected, to say the least.
		if ($v === null || $v === '') {
			$dt = null;
		} elseif ($v instanceof DateTime) {
			$dt = $v;
		} else {
			// some string/numeric value passed; we normalize that so that we can
			// validate it.
			try {
				if (is_numeric($v)) { // if it's a unix timestamp
					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
					// We have to explicitly specify and then change the time zone because of a
					// DateTime bug: http://bugs.php.net/bug.php?id=43003
					$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
				} else {
					$dt = new DateTime($v);
				}
			} catch (Exception $x) {
				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
			}
		}

		if ( $this->updated_at !== null || $dt !== null ) {
			// (nested ifs are a little easier to read in this case)

			$currNorm = ($this->updated_at !== null && $tmpDt = new DateTime($this->updated_at)) ? $tmpDt->format('Y-m-d H:i:s') : null;
			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;

			if ( ($currNorm !== $newNorm) // normalized values don't match
					)
			{
				$this->updated_at = ($dt ? $dt->format('Y-m-d H:i:s') : null);
				$this->modifiedColumns[] = PhotoPeer::UPDATED_AT;
			}
		} // if either are not null

		return $this;
	} // setUpdatedAt()

	/**
	 * Set the value of [show] column.
	 *
	 * @param      boolean $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setShow($v)
	{
		if ($v !== null) {
			$v = (boolean) $v;
		}

		if ($this->show !== $v || $this->isNew()) {
			if ($this->show === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::SHOW;
			}
			$this->show = $v;
		}

		return $this;
	} // setShow()

	/**
	 * Set the value of [order] column.
	 *
	 * @param      int $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setOrder($v)
	{
		if ($v !== null) {
			$v = (int) $v;
		}

		if ($this->order !== $v) {
			if ($this->order === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::ORDER;
			}
			$this->order = $v;
		}

		return $this;
	} // setOrder()

	/**
	 * Set the value of [img] column.
	 *
	 * @param      string $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setImg($v)
	{
		if ($v !== null) {
			$v = (string) $v;
		}

		if ($this->img !== $v) {
			if ($this->img === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::IMG;
			}
			$this->img = $v;
		}

		return $this;
	} // setImg()

	/**
	 * Set the value of [full_path] column.
	 *
	 * @param      string $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setFullPath($v)
	{
		if ($v !== null) {
			$v = (string) $v;
		}

		if ($this->full_path !== $v) {
			if ($this->full_path === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::FULL_PATH;
			}
			$this->full_path = $v;
		}

		return $this;
	} // setFullPath()

	/**
	 * Set the value of [preview_path] column.
	 *
	 * @param      string $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setPreviewPath($v)
	{
		if ($v !== null) {
			$v = (string) $v;
		}

		if ($this->preview_path !== $v) {
			if ($this->preview_path === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::PREVIEW_PATH;
			}
			$this->preview_path = $v;
		}

		return $this;
	} // setPreviewPath()

	/**
	 * Set the value of [thumb_path] column.
	 *
	 * @param      string $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setThumbPath($v)
	{
		if ($v !== null) {
			$v = (string) $v;
		}

		if ($this->thumb_path !== $v) {
			if ($this->thumb_path === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::THUMB_PATH;
			}
			$this->thumb_path = $v;
		}

		return $this;
	} // setThumbPath()

	/**
	 * Set the value of [link] column.
	 *
	 * @param      string $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setLink($v)
	{
		if ($v !== null) {
			$v = (string) $v;
		}

		if ($this->link !== $v) {
			if ($this->link === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::LINK;
			}
			$this->link = $v;
		}

		return $this;
	} // setLink()

	/**
	 * Set the value of [width] column.
	 *
	 * @param      int $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setWidth($v)
	{
		if ($v !== null) {
			$v = (int) $v;
		}

		if ($this->width !== $v) {
			if ($this->width === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::WIDTH;
			}
			$this->width = $v;
		}

		return $this;
	} // setWidth()

	/**
	 * Set the value of [height] column.
	 *
	 * @param      int $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setHeight($v)
	{
		if ($v !== null) {
			$v = (int) $v;
		}

		if ($this->height !== $v) {
			if ($this->height === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::HEIGHT;
			}
			$this->height = $v;
		}

		return $this;
	} // setHeight()

	/**
	 * Set the value of [carousel] column.
	 *
	 * @param      boolean $v new value
	 * @return     Photo The current object (for fluent API support)
	 */
	public function setCarousel($v)
	{
		if ($v !== null) {
			$v = (boolean) $v;
		}

		if ($this->carousel !== $v || $this->isNew()) {
			if ($this->carousel === null && $v === '') {
			} else {
			  $this->modifiedColumns[] = PhotoPeer::CAROUSEL;
			}
			$this->carousel = $v;
		}

		return $this;
	} // setCarousel()

	/**
	 * Indicates whether the columns in this object are only set to default values.
	 *
	 * This method can be used in conjunction with isModified() to indicate whether an object is both
	 * modified _and_ has some values set which are non-default.
	 *
	 * @return     boolean Whether the columns in this object are only been set with default values.
	 */
	public function hasOnlyDefaultValues()
	{
			if ($this->show !== true) {
				return false;
			}

			if ($this->carousel !== false) {
				return false;
			}

		// otherwise, everything was equal, so return TRUE
		return true;
	} // hasOnlyDefaultValues()

	/**
	 * Hydrates (populates) the object variables with values from the database resultset.
	 *
	 * An offset (0-based "start column") is specified so that objects can be hydrated
	 * with a subset of the columns in the resultset rows.  This is needed, for example,
	 * for results of JOIN queries where the resultset row includes columns from two or
	 * more tables.
	 *
	 * @param      array $row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
	 * @param      int $startcol 0-based offset column which indicates which restultset column to start with.
	 * @param      boolean $rehydrate Whether this object is being re-hydrated from the database.
	 * @return     int next starting column
	 * @throws     PropelException  - Any caught Exception will be rewrapped as a PropelException.
	 */
	public function hydrate($row, $startcol = 0, $rehydrate = false)
	{
		try {

			$this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
			$this->photoalbum_id = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null;
			$this->created_at = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null;
			$this->updated_at = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null;
			$this->show = ($row[$startcol + 4] !== null) ? (boolean) $row[$startcol + 4] : null;
			$this->order = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null;
			$this->img = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null;
			$this->full_path = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null;
			$this->preview_path = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null;
			$this->thumb_path = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null;
			$this->link = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null;
			$this->width = ($row[$startcol + 11] !== null) ? (int) $row[$startcol + 11] : null;
			$this->height = ($row[$startcol + 12] !== null) ? (int) $row[$startcol + 12] : null;
			$this->carousel = ($row[$startcol + 13] !== null) ? (boolean) $row[$startcol + 13] : null;
			$this->resetModified();

			$this->setNew(false);

			if ($rehydrate) {
				$this->ensureConsistency();
			}

			// FIXME - using NUM_COLUMNS may be clearer.
			return $startcol + 14; // 14 = PhotoPeer::NUM_COLUMNS - PhotoPeer::NUM_LAZY_LOAD_COLUMNS).

		} catch (Exception $e) {
			throw new PropelException("Error populating Photo object", $e);
		}
	}

	/**
	 * Checks and repairs the internal consistency of the object.
	 *
	 * This method is executed after an already-instantiated object is re-hydrated
	 * from the database.  It exists to check any foreign keys to make sure that
	 * the objects related to the current object are correct based on foreign key.
	 *
	 * You can override this method in the stub class, but you should always invoke
	 * the base method from the overridden method (i.e. parent::ensureConsistency()),
	 * in case your model changes.
	 *
	 * @throws     PropelException
	 */
	public function ensureConsistency()
	{

		if ($this->aPhotoalbum !== null && $this->photoalbum_id !== $this->aPhotoalbum->getId()) {
			$this->aPhotoalbum = null;
		}
	} // ensureConsistency

	/**
	 * Reloads this object from datastore based on primary key and (optionally) resets all associated objects.
	 *
	 * This will only work if the object has been saved and has a valid primary key set.
	 *
	 * @param      boolean $deep (optional) Whether to also de-associated any related objects.
	 * @param      PropelPDO $con (optional) The PropelPDO connection to use.
	 * @return     void
	 * @throws     PropelException - if this object is deleted, unsaved or doesn't have pk match in db
	 */
	public function reload($deep = false, PropelPDO $con = null)
	{
		if ($this->isDeleted()) {
			throw new PropelException("Cannot reload a deleted object.");
		}

		if ($this->isNew()) {
			throw new PropelException("Cannot reload an unsaved object.");
		}

		if ($con === null) {
			$con = Propel::getConnection(PhotoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
		}

		// We don't need to alter the object instance pool; we're just modifying this instance
		// already in the pool.

		$stmt = PhotoPeer::doSelectStmt($this->buildPkeyCriteria(), $con);
		$row = $stmt->fetch(PDO::FETCH_NUM);
		$stmt->closeCursor();
		if (!$row) {
			throw new PropelException('Cannot find matching row in the database to reload object values.');
		}
		$this->hydrate($row, 0, true); // rehydrate

		if ($deep) {  // also de-associate any related objects?

			$this->aPhotoalbum = null;
			$this->collPhotoI18ns = null;
			$this->lastPhotoI18nCriteria = null;

		} // if (deep)
	}

	/**
	 * Removes this object from datastore and sets delete attribute.
	 *
	 * @param      PropelPDO $con
	 * @return     void
	 * @throws     PropelException
	 * @see        BaseObject::setDeleted()
	 * @see        BaseObject::isDeleted()
	 */
	public function delete(PropelPDO $con = null)
	{
		if ($this->isDeleted()) {
			throw new PropelException("This object has already been deleted.");
		}

		if ($con === null) {
			$con = Propel::getConnection(PhotoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
		}

		$con->beginTransaction();
		try {
			$ret = $this->preDelete($con);
			// symfony_behaviors behavior
			foreach (sfMixer::getCallables('BasePhoto:delete:pre') as $callable)
			{
			  if (call_user_func($callable, $this, $con))
			  {
			    $con->commit();

			    return;
			  }
			}

			if ($ret) {
				PhotoPeer::doDelete($this, $con);
				$this->postDelete($con);
				// symfony_behaviors behavior
				foreach (sfMixer::getCallables('BasePhoto:delete:post') as $callable)
				{
				  call_user_func($callable, $this, $con);
				}

				$this->setDeleted(true);
				$con->commit();
			} else {
				$con->commit();
			}
		} catch (PropelException $e) {
			$con->rollBack();
			throw $e;
		}
	}

	/**
	 * Persists this object to the database.
	 *
	 * If the object is new, it inserts it; otherwise an update is performed.
	 * All modified related objects will also be persisted in the doSave()
	 * method.  This method wraps all precipitate database operations in a
	 * single transaction.
	 *
	 * @param      PropelPDO $con
	 * @return     int The number of rows affected by this insert/update and any referring fk objects' save() operations.
	 * @throws     PropelException
	 * @see        doSave()
	 */
	public function save(PropelPDO $con = null)
	{
		if ($this->isDeleted()) {
			throw new PropelException("You cannot save an object that has been deleted.");
		}

		if ($con === null) {
			$con = Propel::getConnection(PhotoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
		}

		$con->beginTransaction();
		$isInsert = $this->isNew();
		try {
			$ret = $this->preSave($con);
			// symfony_behaviors behavior
			foreach (sfMixer::getCallables('BasePhoto:save:pre') as $callable)
			{
			  if (is_integer($affectedRows = call_user_func($callable, $this, $con)))
			  {
			    $con->commit();

			    return $affectedRows;
			  }
			}

			// symfony_timestampable behavior
			if ($this->isModified() && !$this->isColumnModified(PhotoPeer::UPDATED_AT) && $this->getChangeUpdatedAt())
			{
			  $this->setUpdatedAt(time());
			}
			if ($isInsert) {
				$ret = $ret && $this->preInsert($con);
				// symfony_timestampable behavior
				if (!$this->isColumnModified(PhotoPeer::CREATED_AT))
				{
				  $this->setCreatedAt(time());
				}

			} else {
				$ret = $ret && $this->preUpdate($con);
			}
			if ($ret) {
				$affectedRows = $this->doSave($con);
				if ($isInsert) {
					$this->postInsert($con);
				} else {
					$this->postUpdate($con);
				}
				$this->postSave($con);
				// symfony_behaviors behavior
				foreach (sfMixer::getCallables('BasePhoto:save:post') as $callable)
				{
				  call_user_func($callable, $this, $con, $affectedRows);
				}

				PhotoPeer::addInstanceToPool($this);
			} else {
				$affectedRows = 0;
			}
			$con->commit();
			return $affectedRows;
		} catch (PropelException $e) {
			$con->rollBack();
			throw $e;
		}
	}

	/**
	 * Performs the work of inserting or updating the row in the database.
	 *
	 * If the object is new, it inserts it; otherwise an update is performed.
	 * All related objects are also updated in this method.
	 *
	 * @param      PropelPDO $con
	 * @return     int The number of rows affected by this insert/update and any referring fk objects' save() operations.
	 * @throws     PropelException
	 * @see        save()
	 */
	protected function doSave(PropelPDO $con)
	{
		$affectedRows = 0; // initialize var to track total num of affected rows
		if (!$this->alreadyInSave) {
			$this->alreadyInSave = true;

			// We call the save method on the following object(s) if they
			// were passed to this object by their coresponding set
			// method.  This object relates to these object(s) by a
			// foreign key reference.

			if ($this->aPhotoalbum !== null) {
				if ($this->aPhotoalbum->isModified() || $this->aPhotoalbum->isNew()) {
					$affectedRows += $this->aPhotoalbum->save($con);
				}
				$this->setPhotoalbum($this->aPhotoalbum);
			}

			if ($this->isNew() ) {
				$this->modifiedColumns[] = PhotoPeer::ID;
			}

			// If this object has been modified, then save it to the database.
			if ($this->isModified()) {
				if ($this->isNew()) {
					// if i18n object is new and all fields are empty we do not save it into DB
					$has_non_empty_fields = false;
					$only_service_fields_modified = true;
					$is_i18n = false;
					foreach ($this->getModifiedColumns() as $modified_column) {
						// news_i18n.UPDATED_AT_EXTRA -> UpdatedAtExtra
						if (strstr($modified_column, 'i18n')) {
							$is_i18n = true;
						}
						$modified_column_name = preg_replace("/^[^\.]+\./", '', $modified_column);
						// we do not take into account changing of some of the fields
						if (in_array($modified_column_name, array('ID', 'CULTURE', 'UPDATED_AT', 'UPDATED_AT_EXTRA'))) {
							continue;
						}
						$only_service_fields_modified = false;
						// news_i18n.UPDATED_AT_EXTRA -> news_i18n.UpdatedAtExtra
						$modified_column_name_parts = explode('_', $modified_column_name);
						$modified_column_name = '';
						foreach ($modified_column_name_parts as $part) {
							$modified_column_name .= ucfirst(strtolower($part));
						}

						$value = $this->getByName($modified_column_name);

						if ($value) {
							$has_non_empty_fields = true;
							break;
						}
					}
					if ($has_non_empty_fields || ($only_service_fields_modified && !$is_i18n)) {
						$pk = PhotoPeer::doInsert($this, $con);
						$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which
										 // should always be true here (even though technically
										 // BasePeer::doInsert() can insert multiple rows).

						$this->setId($pk);  //[IMV] update autoincrement primary key

						$this->setNew(false);
					}
				} else {
					$affectedRows += PhotoPeer::doUpdate($this, $con);
				}

				$this->resetModified(); // [HL] After being saved an object is no longer 'modified'
			}

			if ($this->collPhotoI18ns !== null) {
				foreach ($this->collPhotoI18ns as $referrerFK) {
					if (!$referrerFK->isDeleted()) {
						$affectedRows += $referrerFK->save($con);
					}
				}
			}

			$this->alreadyInSave = false;

		}
		return $affectedRows;
	} // doSave()

	/**
	 * Array of ValidationFailed objects.
	 * @var        array ValidationFailed[]
	 */
	protected $validationFailures = array();

	/**
	 * Gets any ValidationFailed objects that resulted from last call to validate().
	 *
	 *
	 * @return     array ValidationFailed[]
	 * @see        validate()
	 */
	public function getValidationFailures()
	{
		return $this->validationFailures;
	}

	/**
	 * Validates the objects modified field values and all objects related to this table.
	 *
	 * If $columns is either a column name or an array of column names
	 * only those columns are validated.
	 *
	 * @param      mixed $columns Column name or an array of column names.
	 * @return     boolean Whether all columns pass validation.
	 * @see        doValidate()
	 * @see        getValidationFailures()
	 */
	public function validate($columns = null)
	{
		$res = $this->doValidate($columns);
		if ($res === true) {
			$this->validationFailures = array();
			return true;
		} else {
			$this->validationFailures = $res;
			return false;
		}
	}

	/**
	 * This function performs the validation work for complex object models.
	 *
	 * In addition to checking the current object, all related objects will
	 * also be validated.  If all pass then <code>true</code> is returned; otherwise
	 * an aggreagated array of ValidationFailed objects will be returned.
	 *
	 * @param      array $columns Array of column names to validate.
	 * @return     mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise.
	 */
	protected function doValidate($columns = null)
	{
		if (!$this->alreadyInValidation) {
			$this->alreadyInValidation = true;
			$retval = null;

			$failureMap = array();

			// We call the validate method on the following object(s) if they
			// were passed to this object by their coresponding set
			// method.  This object relates to these object(s) by a
			// foreign key reference.

			if ($this->aPhotoalbum !== null) {
				if (!$this->aPhotoalbum->validate($columns)) {
					$failureMap = array_merge($failureMap, $this->aPhotoalbum->getValidationFailures());
				}
			}

			if (($retval = PhotoPeer::doValidate($this, $columns)) !== true) {
				$failureMap = array_merge($failureMap, $retval);
			}

				if ($this->collPhotoI18ns !== null) {
					foreach ($this->collPhotoI18ns as $referrerFK) {
						if (!$referrerFK->validate($columns)) {
							$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
						}
					}
				}

			$this->alreadyInValidation = false;
		}

		return (!empty($failureMap) ? $failureMap : true);
	}

	/**
	 * Retrieves a field from the object by name passed in as a string.
	 *
	 * @param      string $name name
	 * @param      string $type The type of fieldname the $name is of:
	 *                     one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
	 *                     BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
	 * @return     mixed Value of field.
	 */
	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
	{
		$pos = PhotoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
		$field = $this->getByPosition($pos);
		return $field;
	}

	/**
	 * Retrieves a field from the object by Position as specified in the xml schema.
	 * Zero-based.
	 *
	 * @param      int $pos position in xml schema
	 * @return     mixed Value of field at $pos
	 */
	public function getByPosition($pos)
	{
		switch($pos) {
			case 0:
				return $this->getId();
				break;
			case 1:
				return $this->getPhotoalbumId();
				break;
			case 2:
				return $this->getCreatedAt();
				break;
			case 3:
				return $this->getUpdatedAt();
				break;
			case 4:
				return $this->getShow();
				break;
			case 5:
				return $this->getOrder();
				break;
			case 6:
				return $this->getImg();
				break;
			case 7:
				return $this->getFullPath();
				break;
			case 8:
				return $this->getPreviewPath();
				break;
			case 9:
				return $this->getThumbPath();
				break;
			case 10:
				return $this->getLink();
				break;
			case 11:
				return $this->getWidth();
				break;
			case 12:
				return $this->getHeight();
				break;
			case 13:
				return $this->getCarousel();
				break;
			default:
				return null;
				break;
		} // switch()
	}

	/**
	 * Exports the object as an array.
	 *
	 * You can specify the key type of the array by passing one of the class
	 * type constants.
	 *
	 * @param      string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
	 *                        BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. Defaults to BasePeer::TYPE_PHPNAME.
	 * @param      boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns.  Defaults to TRUE.
	 * @return     an associative array containing the field names (as keys) and field values
	 */
	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
	{
		$keys = PhotoPeer::getFieldNames($keyType);
		$result = array(
			$keys[0] => $this->getId(),
			$keys[1] => $this->getPhotoalbumId(),
			$keys[2] => $this->getCreatedAt(),
			$keys[3] => $this->getUpdatedAt(),
			$keys[4] => $this->getShow(),
			$keys[5] => $this->getOrder(),
			$keys[6] => $this->getImg(),
			$keys[7] => $this->getFullPath(),
			$keys[8] => $this->getPreviewPath(),
			$keys[9] => $this->getThumbPath(),
			$keys[10] => $this->getLink(),
			$keys[11] => $this->getWidth(),
			$keys[12] => $this->getHeight(),
			$keys[13] => $this->getCarousel(),
		);
		return $result;
	}

	/**
	 * Sets a field from the object by name passed in as a string.
	 *
	 * @param      string $name peer name
	 * @param      mixed $value field value
	 * @param      string $type The type of fieldname the $name is of:
	 *                     one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
	 *                     BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
	 * @return     void
	 */
	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
	{
		$pos = PhotoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
		return $this->setByPosition($pos, $value);
	}

	/**
	 * Sets a field from the object by Position as specified in the xml schema.
	 * Zero-based.
	 *
	 * @param      int $pos position in xml schema
	 * @param      mixed $value field value
	 * @return     void
	 */
	public function setByPosition($pos, $value)
	{
		switch($pos) {
			case 0:
				$this->setId($value);
				break;
			case 1:
				$this->setPhotoalbumId($value);
				break;
			case 2:
				$this->setCreatedAt($value);
				break;
			case 3:
				$this->setUpdatedAt($value);
				break;
			case 4:
				$this->setShow($value);
				break;
			case 5:
				$this->setOrder($value);
				break;
			case 6:
				$this->setImg($value);
				break;
			case 7:
				$this->setFullPath($value);
				break;
			case 8:
				$this->setPreviewPath($value);
				break;
			case 9:
				$this->setThumbPath($value);
				break;
			case 10:
				$this->setLink($value);
				break;
			case 11:
				$this->setWidth($value);
				break;
			case 12:
				$this->setHeight($value);
				break;
			case 13:
				$this->setCarousel($value);
				break;
		} // switch()
	}

	/**
	 * Populates the object using an array.
	 *
	 * This is particularly useful when populating an object from one of the
	 * request arrays (e.g. $_POST).  This method goes through the column
	 * names, checking to see whether a matching key exists in populated
	 * array. If so the setByName() method is called for that column.
	 *
	 * You can specify the key type of the array by additionally passing one
	 * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
	 * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
	 * The default key type is the column's phpname (e.g. 'AuthorId')
	 *
	 * @param      array  $arr     An array to populate the object from.
	 * @param      string $keyType The type of keys the array uses.
	 * @return     void
	 */
	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
	{
		$keys = PhotoPeer::getFieldNames($keyType);

		if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]);
		if (array_key_exists($keys[1], $arr)) $this->setPhotoalbumId($arr[$keys[1]]);
		if (array_key_exists($keys[2], $arr)) $this->setCreatedAt($arr[$keys[2]]);
		if (array_key_exists($keys[3], $arr)) $this->setUpdatedAt($arr[$keys[3]]);
		if (array_key_exists($keys[4], $arr)) $this->setShow($arr[$keys[4]]);
		if (array_key_exists($keys[5], $arr)) $this->setOrder($arr[$keys[5]]);
		if (array_key_exists($keys[6], $arr)) $this->setImg($arr[$keys[6]]);
		if (array_key_exists($keys[7], $arr)) $this->setFullPath($arr[$keys[7]]);
		if (array_key_exists($keys[8], $arr)) $this->setPreviewPath($arr[$keys[8]]);
		if (array_key_exists($keys[9], $arr)) $this->setThumbPath($arr[$keys[9]]);
		if (array_key_exists($keys[10], $arr)) $this->setLink($arr[$keys[10]]);
		if (array_key_exists($keys[11], $arr)) $this->setWidth($arr[$keys[11]]);
		if (array_key_exists($keys[12], $arr)) $this->setHeight($arr[$keys[12]]);
		if (array_key_exists($keys[13], $arr)) $this->setCarousel($arr[$keys[13]]);
	}

	/**
	 * Build a Criteria object containing the values of all modified columns in this object.
	 *
	 * @return     Criteria The Criteria object containing all modified values.
	 */
	public function buildCriteria()
	{
		$criteria = new Criteria(PhotoPeer::DATABASE_NAME);

		if ($this->isColumnModified(PhotoPeer::ID)) $criteria->add(PhotoPeer::ID, $this->id);
		if ($this->isColumnModified(PhotoPeer::PHOTOALBUM_ID)) $criteria->add(PhotoPeer::PHOTOALBUM_ID, $this->photoalbum_id);
		if ($this->isColumnModified(PhotoPeer::CREATED_AT)) $criteria->add(PhotoPeer::CREATED_AT, $this->created_at);
		if ($this->isColumnModified(PhotoPeer::UPDATED_AT)) $criteria->add(PhotoPeer::UPDATED_AT, $this->updated_at);
		if ($this->isColumnModified(PhotoPeer::SHOW)) $criteria->add(PhotoPeer::SHOW, $this->show);
		if ($this->isColumnModified(PhotoPeer::ORDER)) $criteria->add(PhotoPeer::ORDER, $this->order);
		if ($this->isColumnModified(PhotoPeer::IMG)) $criteria->add(PhotoPeer::IMG, $this->img);
		if ($this->isColumnModified(PhotoPeer::FULL_PATH)) $criteria->add(PhotoPeer::FULL_PATH, $this->full_path);
		if ($this->isColumnModified(PhotoPeer::PREVIEW_PATH)) $criteria->add(PhotoPeer::PREVIEW_PATH, $this->preview_path);
		if ($this->isColumnModified(PhotoPeer::THUMB_PATH)) $criteria->add(PhotoPeer::THUMB_PATH, $this->thumb_path);
		if ($this->isColumnModified(PhotoPeer::LINK)) $criteria->add(PhotoPeer::LINK, $this->link);
		if ($this->isColumnModified(PhotoPeer::WIDTH)) $criteria->add(PhotoPeer::WIDTH, $this->width);
		if ($this->isColumnModified(PhotoPeer::HEIGHT)) $criteria->add(PhotoPeer::HEIGHT, $this->height);
		if ($this->isColumnModified(PhotoPeer::CAROUSEL)) $criteria->add(PhotoPeer::CAROUSEL, $this->carousel);

		return $criteria;
	}

	/**
	 * Builds a Criteria object containing the primary key for this object.
	 *
	 * Unlike buildCriteria() this method includes the primary key values regardless
	 * of whether or not they have been modified.
	 *
	 * @return     Criteria The Criteria object containing value(s) for primary key(s).
	 */
	public function buildPkeyCriteria()
	{
		$criteria = new Criteria(PhotoPeer::DATABASE_NAME);

		$criteria->add(PhotoPeer::ID, $this->id);

		return $criteria;
	}

	/**
	 * Returns the primary key for this object (row).
	 * @return     int
	 */
	public function getPrimaryKey()
	{
		return $this->getId();
	}

	/**
	 * Generic method to set the primary key (id column).
	 *
	 * @param      int $key Primary key.
	 * @return     void
	 */
	public function setPrimaryKey($key)
	{
		$this->setId($key);
	}

	/**
	 * Sets contents of passed object to values from current object.
	 *
	 * If desired, this method can also make copies of all associated (fkey referrers)
	 * objects.
	 *
	 * @param      object $copyObj An object of Photo (or compatible) type.
	 * @param      boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
	 * @throws     PropelException
	 */
	public function copyInto($copyObj, $deepCopy = false)
	{

		$copyObj->setPhotoalbumId($this->photoalbum_id);

		$copyObj->setCreatedAt($this->created_at);

		$copyObj->setUpdatedAt($this->updated_at);

		$copyObj->setShow($this->show);

		$copyObj->setOrder($this->order);

		$copyObj->setImg($this->img);

		$copyObj->setFullPath($this->full_path);

		$copyObj->setPreviewPath($this->preview_path);

		$copyObj->setThumbPath($this->thumb_path);

		$copyObj->setLink($this->link);

		$copyObj->setWidth($this->width);

		$copyObj->setHeight($this->height);

		$copyObj->setCarousel($this->carousel);

		if ($deepCopy) {
			// important: temporarily setNew(false) because this affects the behavior of
			// the getter/setter methods for fkey referrer objects.
			$copyObj->setNew(false);

			foreach ($this->getPhotoI18ns() as $relObj) {
				if ($relObj !== $this) {  // ensure that we don't try to copy a reference to ourselves
					$copyObj->addPhotoI18n($relObj->copy($deepCopy));
				}
			}

		} // if ($deepCopy)

		$copyObj->setNew(true);

		$copyObj->setId(NULL); // this is a auto-increment column, so set to default value

	}

	/**
	 * Makes a copy of this object that will be inserted as a new row in table when saved.
	 * It creates a new object filling in the simple attributes, but skipping any primary
	 * keys that are defined for the table.
	 *
	 * If desired, this method can also make copies of all associated (fkey referrers)
	 * objects.
	 *
	 * @param      boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
	 * @return     Photo Clone of current object.
	 * @throws     PropelException
	 */
	public function copy($deepCopy = false)
	{
		// we use get_class(), because this might be a subclass
		$clazz = get_class($this);
		$copyObj = new $clazz();
		$this->copyInto($copyObj, $deepCopy);
		return $copyObj;
	}

	/**
	 * Returns a peer instance associated with this om.
	 *
	 * Since Peer classes are not to have any instance attributes, this method returns the
	 * same instance for all member of this class. The method could therefore
	 * be static, but this would prevent one from overriding the behavior.
	 *
	 * @return     PhotoPeer
	 */
	public function getPeer()
	{
		if (self::$peer === null) {
			self::$peer = new PhotoPeer();
		}
		return self::$peer;
	}

	/**
	 * Declares an association between this object and a Photoalbum object.
	 *
	 * @param      Photoalbum $v
	 * @return     Photo The current object (for fluent API support)
	 * @throws     PropelException
	 */
	public function setPhotoalbum(Photoalbum $v = null)
	{
		if ($v === null) {
			$this->setPhotoalbumId(NULL);
		} else {
			$this->setPhotoalbumId($v->getId());
		}

		$this->aPhotoalbum = $v;

		// Add binding for other direction of this n:n relationship.
		// If this object has already been added to the Photoalbum object, it will not be re-added.
		if ($v !== null) {
			$v->addPhoto($this);
		}

		return $this;
	}

	/**
	 * Get the associated Photoalbum object
	 *
	 * @param      PropelPDO Optional Connection object.
	 * @return     Photoalbum The associated Photoalbum object.
	 * @throws     PropelException
	 */
	public function getPhotoalbum(PropelPDO $con = null)
	{
		if ($this->aPhotoalbum === null && ($this->photoalbum_id !== null)) {
			$this->aPhotoalbum = PhotoalbumPeer::retrieveByPk($this->photoalbum_id);
			/* The following can be used additionally to
			   guarantee the related object contains a reference
			   to this object.  This level of coupling may, however, be
			   undesirable since it could result in an only partially populated collection
			   in the referenced object.
			   $this->aPhotoalbum->addPhotos($this);
			 */
		}
		return $this->aPhotoalbum;
	}

	/**
	 * Clears out the collPhotoI18ns collection (array).
	 *
	 * This does not modify the database; however, it will remove any associated objects, causing
	 * them to be refetched by subsequent calls to accessor method.
	 *
	 * @return     void
	 * @see        addPhotoI18ns()
	 */
	public function clearPhotoI18ns()
	{
		$this->collPhotoI18ns = null; // important to set this to NULL since that means it is uninitialized
	}

	/**
	 * Initializes the collPhotoI18ns collection (array).
	 *
	 * By default this just sets the collPhotoI18ns collection to an empty array (like clearcollPhotoI18ns());
	 * however, you may wish to override this method in your stub class to provide setting appropriate
	 * to your application -- for example, setting the initial array to the values stored in database.
	 *
	 * @return     void
	 */
	public function initPhotoI18ns()
	{
		$this->collPhotoI18ns = array();
	}

	/**
	 * Gets an array of PhotoI18n objects which contain a foreign key that references this object.
	 *
	 * If this collection has already been initialized with an identical Criteria, it returns the collection.
	 * Otherwise if this Photo has previously been saved, it will retrieve
	 * related PhotoI18ns from storage. If this Photo is new, it will return
	 * an empty collection or the current collection, the criteria is ignored on a new object.
	 *
	 * @param      PropelPDO $con
	 * @param      Criteria $criteria
	 * @return     array PhotoI18n[]
	 * @throws     PropelException
	 */
	public function getPhotoI18ns($criteria = null, PropelPDO $con = null)
	{
		if ($criteria === null) {
			$criteria = new Criteria(PhotoPeer::DATABASE_NAME);
		}
		elseif ($criteria instanceof Criteria)
		{
			$criteria = clone $criteria;
		}

		if ($this->collPhotoI18ns === null) {
			if ($this->isNew()) {
			   $this->collPhotoI18ns = array();
			} else {

				$criteria->add(PhotoI18nPeer::ID, $this->id);

				PhotoI18nPeer::addSelectColumns($criteria);
				$this->collPhotoI18ns = PhotoI18nPeer::doSelect($criteria, $con);
			}
		} else {
			// criteria has no effect for a new object
			if (!$this->isNew()) {
				// the following code is to determine if a new query is
				// called for.  If the criteria is the same as the last
				// one, just return the collection.

				$criteria->add(PhotoI18nPeer::ID, $this->id);

				PhotoI18nPeer::addSelectColumns($criteria);
				if (!isset($this->lastPhotoI18nCriteria) || !$this->lastPhotoI18nCriteria->equals($criteria)) {
					$this->collPhotoI18ns = PhotoI18nPeer::doSelect($criteria, $con);
				}
			}
		}
		$this->lastPhotoI18nCriteria = $criteria;
		return $this->collPhotoI18ns;
	}

	/**
	 * Returns the number of related PhotoI18n objects.
	 *
	 * @param      Criteria $criteria
	 * @param      boolean $distinct
	 * @param      PropelPDO $con
	 * @return     int Count of related PhotoI18n objects.
	 * @throws     PropelException
	 */
	public function countPhotoI18ns(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
	{
		if ($criteria === null) {
			$criteria = new Criteria(PhotoPeer::DATABASE_NAME);
		} else {
			$criteria = clone $criteria;
		}

		if ($distinct) {
			$criteria->setDistinct();
		}

		$count = null;

		if ($this->collPhotoI18ns === null) {
			if ($this->isNew()) {
				$count = 0;
			} else {

				$criteria->add(PhotoI18nPeer::ID, $this->id);

				$count = PhotoI18nPeer::doCount($criteria, false, $con);
			}
		} else {
			// criteria has no effect for a new object
			if (!$this->isNew()) {
				// the following code is to determine if a new query is
				// called for.  If the criteria is the same as the last
				// one, just return count of the collection.

				$criteria->add(PhotoI18nPeer::ID, $this->id);

				if (!isset($this->lastPhotoI18nCriteria) || !$this->lastPhotoI18nCriteria->equals($criteria)) {
					$count = PhotoI18nPeer::doCount($criteria, false, $con);
				} else {
					$count = count($this->collPhotoI18ns);
				}
			} else {
				$count = count($this->collPhotoI18ns);
			}
		}
		return $count;
	}

	/**
	 * Method called to associate a PhotoI18n object to this object
	 * through the PhotoI18n foreign key attribute.
	 *
	 * @param      PhotoI18n $l PhotoI18n
	 * @return     void
	 * @throws     PropelException
	 */
	public function addPhotoI18n(PhotoI18n $l)
	{
		if ($this->collPhotoI18ns === null) {
			$this->initPhotoI18ns();
		}
		if (!in_array($l, $this->collPhotoI18ns, true)) { // only add it if the **same** object is not already associated
			array_push($this->collPhotoI18ns, $l);
			$l->setPhoto($this);
		}
	}

	/**
	 * Resets all collections of referencing foreign keys.
	 *
	 * This method is a user-space workaround for PHP's inability to garbage collect objects
	 * with circular references.  This is currently necessary when using Propel in certain
	 * daemon or large-volumne/high-memory operations.
	 *
	 * @param      boolean $deep Whether to also clear the references on all associated objects.
	 */
	public function clearAllReferences($deep = false)
	{
		if ($deep) {
			if ($this->collPhotoI18ns) {
				foreach ((array) $this->collPhotoI18ns as $o) {
					$o->clearAllReferences($deep);
				}
			}
		} // if ($deep)

		$this->collPhotoI18ns = null;
			$this->aPhotoalbum = null;
	}

	// symfony_behaviors behavior

	/**
	 * Calls methods defined via {@link sfMixer}.
	 */
	public function __call($method, $arguments)
	{
	  if (!$callable = sfMixer::getCallable('BasePhoto:'.$method))
	  {
	    throw new sfException(sprintf('Call to undefined method BasePhoto::%s', $method));
	  }

	  array_unshift($arguments, $this);

	  return call_user_func_array($callable, $arguments);
	}

	// symfony_i18n behavior

	/**
	 * Returns the culture.
	 *
	 * @return string The culture
	 */
	public function getCulture()
	{
	  return $this->culture;
	}

	/**
	 * Sets the culture.
	 *
	 * @param string  The culture to set
	 *
	 * @return Photo
	 */
	public function setCulture($culture)
	{
	  $this->culture = $culture;
	  return $this;
	}

	/**
	 * Returns the "updated_at_extra" value from the current {@link PhotoI18n}.
	 */
	public function getUpdatedAtExtra($culture = null)
	{
	  return $this->getCurrentPhotoI18n($culture)->getUpdatedAtExtra();
	}

	/**
	 * Sets the "updated_at_extra" value of the current {@link PhotoI18n}.
	 *
	 * @return Photo
	 */
	public function setUpdatedAtExtra($value, $culture = null)
	{
	  $this->getCurrentPhotoI18n($culture)->setUpdatedAtExtra($value);
	  return $this;
	}

	/**
	 * Returns the "title" value from the current {@link PhotoI18n}.
	 */
	public function getTitle($culture = null)
	{
	  return $this->getCurrentPhotoI18n($culture)->getTitle();
	}

	/**
	 * Sets the "title" value of the current {@link PhotoI18n}.
	 *
	 * @return Photo
	 */
	public function setTitle($value, $culture = null)
	{
	  $this->getCurrentPhotoI18n($culture)->setTitle($value);
	  return $this;
	}

	/**
	 * Returns the "body" value from the current {@link PhotoI18n}.
	 */
	public function getBody($culture = null)
	{
	  return $this->getCurrentPhotoI18n($culture)->getBody();
	}

	/**
	 * Sets the "body" value of the current {@link PhotoI18n}.
	 *
	 * @return Photo
	 */
	public function setBody($value, $culture = null)
	{
	  $this->getCurrentPhotoI18n($culture)->setBody($value);
	  return $this;
	}

	/**
	 * Returns the "author" value from the current {@link PhotoI18n}.
	 */
	public function getAuthor($culture = null)
	{
	  return $this->getCurrentPhotoI18n($culture)->getAuthor();
	}

	/**
	 * Sets the "author" value of the current {@link PhotoI18n}.
	 *
	 * @return Photo
	 */
	public function setAuthor($value, $culture = null)
	{
	  $this->getCurrentPhotoI18n($culture)->setAuthor($value);
	  return $this;
	}

	/**
	 * Returns the current translation.
	 *
	 * @return PhotoI18n
	 */
	public function getCurrentPhotoI18n($culture = null)
	{
	  if (null === $culture)
	  {
	    $culture = null === $this->culture ? sfPropel::getDefaultCulture() : $this->culture;
	  }

	  if (!isset($this->current_i18n[$culture]))
	  {
	    $object = $this->isNew() ? null : PhotoI18nPeer::retrieveByPK($this->getPrimaryKey(), $culture);
	    if ($object)
	    {
	      $this->setPhotoI18nForCulture($object, $culture);
	    }
	    else
	    {
	      $this->setPhotoI18nForCulture(new PhotoI18n(), $culture);
	      $this->current_i18n[$culture]->setCulture($culture);
	    }
	  }

	  return $this->current_i18n[$culture];
	}

	/**
	 * Sets the translation object for a culture.
	 */
	public function setPhotoI18nForCulture(PhotoI18n $object, $culture)
	{
	  $this->current_i18n[$culture] = $object;
	  $this->addPhotoI18n($object);
	}

} // BasePhoto


text:
<!DOCTYPE html>
<html>

<!-- Mirrored from webapplayers.com/inspinia_admin-v2.1/404.html by HTTrack Website Copier/3.x [XR&CO'2013], Thu, 04 Jun 2015 20:22:54 GMT -->
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>INSPINIA | 404 Error</title>

    <link href="<?=base_url()?>public/css/bootstrap.min.css" rel="stylesheet">
    <link href="<?=base_url()?>public/font-awesome/css/font-awesome.css" rel="stylesheet">

    <link href="<?=base_url()?>public/css/animate.css" rel="stylesheet">
    <link href="<?=base_url()?>public/css/style.css" rel="stylesheet">

</head>

<body class="gray-bg">

    <?=$body?>

    <!-- Mainly scripts -->
    <script src="<?=base_url()?>public/js/jquery-2.1.1.js"></script>
    <script src="<?=base_url()?>public/js/bootstrap.min.js"></script>

</body>

</html>

redpajama_set_name: RedPajamaGithub


text: "use strict";window.IntlMessageFormat=require("../../");


text:
namespace app_list {
class AppListShowerDelegate;
class AppListShowerImpl;
class AppListView;

namespace test {

// Accesses private data from an AppListController for testing.
class AppListShowerImplTestApi {
 public:
  explicit AppListShowerImplTestApi(AppListShowerImpl* shower);

  AppListView* view();
  AppListShowerDelegate* shower_delegate();

 private:
  AppListShowerImpl* const shower_;

  DISALLOW_COPY_AND_ASSIGN(AppListShowerImplTestApi);
};

}  // namespace test
}  // namespace app_list

#endif  // UI_APP_LIST_SHOWER_TEST_APP_LIST_SHOWER_IMPL_TEST_API_H_


text:
Inferno Router is a routing library for [Inferno](https://github.com/infernojs/inferno). It is a port of [react-router 4](https://v5.reactrouter.com/web/guides/quick-start) which was refactored into react-router v5.

## Install

```
npm install inferno-router
```

## Features

Same as react-router v4, except react-native support.

Added features from react-router v5:
- NavLink supports passing function to className-attibute
- NavLink supports passing function to style-attibute

See official react-router [documentation](https://v5.reactrouter.com/web/guides/philosophy)

## Usage (client-side)

```js
import { render } from 'inferno';
import { BrowserRouter, Route, Switch, Link } from 'inferno-router';

const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
);

const About = () => (
  <div>
    <h2>About</h2>
  </div>
);

const Topic = ({ match }) => (
  <div>
    <h3>{match.params.topicId}</h3>
  </div>
);

const Topics = ({ match }) => (
  <div>
    <h2>Topics</h2>
    <ul>
      <li>
        <Link to={`${match.url}/rendering`}>Rendering with React</Link>
      </li>
      <li>
        <Link to={`${match.url}/components`}>Components</Link>
      </li>
      <li>
        <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
      </li>
    </ul>

    <Route path={`${match.url}/:topicId`} component={Topic} />
    <Route
      exact
      path={match.url}
      render={() => <h3>Please select a topic.</h3>}
    />
  </div>
);

const MyWebsite = () => (
  <BrowserRouter>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/about">About</Link></li>
        <li><Link to="/topics">Topics</Link></li>
      </ul>
      <hr />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/topics" component={Topics} />
      </Switch>
    </div>
  </BrowserRouter>
);

// Render HTML on the browser
render(<MyWebsite />, document.getElementById("app"));

```

## Usage (server) with express

First, let's create our component to render boilerplate HTML, header, body etc.

```js
// Routes will be rendered into children
export default function Html({ children }) {
  return (
    <html>
      <head>
        <title>My Application</title>
      </head>
      <body>
        <div id="root">{children}</div>
      </body>
    </html>
  );
}
```

```js
import { renderToString } from 'inferno-server';
import { StaticRouter } from 'inferno-router';
import express from 'express';
import Html from './Html';

const app = express();

app.use((req, res, next) => {
  let context = {};
  const content = renderToString(
    <StaticRouter location={req.url} context={context}>
      <Html/>
    </StaticRouter>
  );
  if(context.url){
    return res.redirect(context.url);
  }
  res.send('<!DOCTYPE html>\n' + renderToString(content));
  next();
});
```

## Usage (server) with koa v2

```js
import { renderToString } from 'inferno-server';
import { StaticRouter } from 'inferno-router';
import Koa from 'koa';
import Html from './Html';

const app = new Koa();

app.use(async(ctx, next) => {

  const context = {};
  const content = renderToString(
    <StaticRouter location={ctx.url} context={context}>
      <Html/>
    </StaticRouter>
  );

  // This will contain the URL to redirect to if <Redirect> was used
  if (context.url) {
    return ctx.redirect(context.url)
  }

  ctx.body = '<!DOCTYPE html>\n' + content;
  await next();
});
```

## Differences with React-Router v4

* No "official" react-native support.
* There's no `inferno-router-dom`, all functionality is inside `inferno-router`


text:
FactoryGirl.define do
  factory :key_visual_node_image, class: KeyVisual::Node::Image, traits: [:cms_node] do
    route "key_visual/image"
  end
end


text:
use crate::minmax::Minmax;
use crate::packet;
use crate::recovery::*;

use std::time::Duration;
use std::time::Instant;

pub static BBR: CongestionControlOps = CongestionControlOps {
    on_init,
    reset,
    on_packet_sent,
    on_packets_acked,
    congestion_event,
    collapse_cwnd,
    checkpoint,
    rollback,
    has_custom_pacing,
    debug_fmt,
};

/// A constant specifying the length of the BBR.BtlBw max filter window for
/// BBR.BtlBwFilter, BtlBwFilterLen is 10 packet-timed round trips.
const BTLBW_FILTER_LEN: Duration = Duration::from_secs(10);

/// A constant specifying the minimum time interval between ProbeRTT states: 10
/// secs.
const PROBE_RTT_INTERVAL: Duration = Duration::from_secs(10);

/// A constant specifying the length of the RTProp min filter window.
const RTPROP_FILTER_LEN: Duration = PROBE_RTT_INTERVAL;

/// A constant specifying the minimum gain value that will allow the sending
/// rate to double each round (2/ln(2) ~= 2.89), used in Startup mode for both
/// BBR.pacing_gain and BBR.cwnd_gain.
const BBR_HIGH_GAIN: f64 = 2.89;

/// The minimal cwnd value BBR tries to target using: 4 packets, or 4 * SMSS
const BBR_MIN_PIPE_CWND_PKTS: usize = 4;

/// The number of phases in the BBR ProbeBW gain cycle: 8.
const BBR_GAIN_CYCLE_LEN: usize = 8;

/// A constant specifying the minimum duration for which ProbeRTT state holds
/// inflight to BBRMinPipeCwnd or fewer packets: 200 ms.
const PROBE_RTT_DURATION: Duration = Duration::from_millis(200);

/// Pacing Gain Cycle.
const PACING_GAIN_CYCLE: [f64; BBR_GAIN_CYCLE_LEN] =
    [5.0 / 4.0, 3.0 / 4.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];

/// A constant to check BBR.BtlBW is still growing.
const BTLBW_GROWTH_TARGET: f64 = 1.25;

/// BBR Internal State Machine.
#[derive(Debug, PartialEq, Eq)]
enum BBRStateMachine {
    Startup,
    Drain,
    ProbeBW,
    ProbeRTT,
}

/// BBR Specific State Variables.
pub struct State {
    // The current state of a BBR flow in the BBR state machine.
    state: BBRStateMachine,

    // The current pacing rate for a BBR flow, which controls inter-packet
    // spacing.
    pacing_rate: u64,

    // BBR's estimated bottleneck bandwidth available to the transport flow,
    // estimated from the maximum delivery rate sample in a sliding window.
    btlbw: u64,

    // The max filter used to estimate BBR.BtlBw.
    btlbwfilter: Minmax<u64>,

    // BBR's estimated two-way round-trip propagation delay of the path,
    // estimated from the windowed minimum recent round-trip delay sample.
    rtprop: Duration,

    // The wall clock time at which the current BBR.RTProp sample was obtained.
    rtprop_stamp: Instant,

    // A boolean recording whether the BBR.RTprop has expired and is due for a
    // refresh with an application idle period or a transition into ProbeRTT
    // state.
    rtprop_expired: bool,

    // The dynamic gain factor used to scale BBR.BtlBw to produce
    // BBR.pacing_rate.
    pacing_gain: f64,

    // The dynamic gain factor used to scale the estimated BDP to produce a
    // congestion window (cwnd).
    cwnd_gain: f64,

    // A boolean that records whether BBR estimates that it has ever fully
    // utilized its available bandwidth ("filled the pipe").
    filled_pipe: bool,

    // Count of packet-timed round trips elapsed so far.
    round_count: u64,

    // A boolean that BBR sets to true once per packet-timed round trip,
    // on ACKs that advance BBR.round_count.
    round_start: bool,

    // packet.delivered value denoting the end of a packet-timed round trip.
    next_round_delivered: usize,

    // Timestamp when ProbeRTT state ends.
    probe_rtt_done_stamp: Option<Instant>,

    // Checking if a roundtrip in ProbeRTT state ends.
    probe_rtt_round_done: bool,

    // Checking if in the packet conservation mode during recovery.
    packet_conservation: bool,

    // Saved cwnd before loss recovery.
    prior_cwnd: usize,

    // Checking if restarting from idle.
    idle_restart: bool,

    // Baseline level delivery rate for full pipe estimator.
    full_bw: u64,

    // The number of round for full pipe estimator without much growth.
    full_bw_count: usize,

    // Last time cycle_index is updated.
    cycle_stamp: Instant,

    // Current index of pacing_gain_cycle[].
    cycle_index: usize,

    // The upper bound on the volume of data BBR allows in flight.
    target_cwnd: usize,

    // Whether in the recovery episode.
    in_recovery: bool,

    // Start time of the connection.
    start_time: Instant,

    // Newly marked lost data size in bytes.
    newly_lost_bytes: usize,

    // Newly acked data size in bytes.
    newly_acked_bytes: usize,

    // bytes_in_flight before processing this ACK.
    prior_bytes_in_flight: usize,
}

impl State {
    pub fn new() -> Self {
        let now = Instant::now();

        State {
            state: BBRStateMachine::Startup,

            pacing_rate: 0,

            btlbw: 0,

            btlbwfilter: Minmax::new(0),

            rtprop: Duration::ZERO,

            rtprop_stamp: now,

            rtprop_expired: false,

            pacing_gain: 0.0,

            cwnd_gain: 0.0,

            filled_pipe: false,

            round_count: 0,

            round_start: false,

            next_round_delivered: 0,

            probe_rtt_done_stamp: None,

            probe_rtt_round_done: false,

            packet_conservation: false,

            prior_cwnd: 0,

            idle_restart: false,

            full_bw: 0,

            full_bw_count: 0,

            cycle_stamp: now,

            cycle_index: 0,

            target_cwnd: 0,

            in_recovery: false,

            start_time: now,

            newly_lost_bytes: 0,

            newly_acked_bytes: 0,

            prior_bytes_in_flight: 0,
        }
    }
}

// When entering the recovery episode.
fn bbr_enter_recovery(r: &mut Recovery, now: Instant) {
    r.bbr_state.prior_cwnd = per_ack::bbr_save_cwnd(r);

    r.congestion_window = r.bytes_in_flight +
        r.bbr_state.newly_acked_bytes.max(r.max_datagram_size);
    r.congestion_recovery_start_time = Some(now);

    r.bbr_state.packet_conservation = true;
    r.bbr_state.in_recovery = true;

    // Start round now.
    r.bbr_state.next_round_delivered = r.delivery_rate.delivered();
}

// When exiting the recovery episode.
fn bbr_exit_recovery(r: &mut Recovery) {
    r.congestion_recovery_start_time = None;

    r.bbr_state.packet_conservation = false;
    r.bbr_state.in_recovery = false;

    per_ack::bbr_restore_cwnd(r);
}

// Congestion Control Hooks.
//
fn on_init(r: &mut Recovery) {
    init::bbr_init(r);
}

fn reset(r: &mut Recovery) {
    r.bbr_state = State::new();

    init::bbr_init(r);
}

fn on_packet_sent(r: &mut Recovery, sent_bytes: usize, _now: Instant) {
    r.bytes_in_flight += sent_bytes;

    per_transmit::bbr_on_transmit(r);
}

fn on_packets_acked(
    r: &mut Recovery, packets: &[Acked], _epoch: packet::Epoch, now: Instant,
) {
    r.bbr_state.newly_acked_bytes = packets.iter().fold(0, |acked_bytes, p| {
        r.bbr_state.prior_bytes_in_flight = r.bytes_in_flight;

        per_ack::bbr_update_model_and_state(r, p, now);

        r.bytes_in_flight = r.bytes_in_flight.saturating_sub(p.size);

        acked_bytes + p.size
    });

    if let Some(pkt) = packets.last() {
        if !r.in_congestion_recovery(pkt.time_sent) {
            // Upon exiting loss recovery.
            bbr_exit_recovery(r);
        }
    }

    per_ack::bbr_update_control_parameters(r, now);

    r.bbr_state.newly_lost_bytes = 0;
}

fn congestion_event(
    r: &mut Recovery, lost_bytes: usize, time_sent: Instant,
    _epoch: packet::Epoch, now: Instant,
) {
    r.bbr_state.newly_lost_bytes = lost_bytes;

    // Upon entering Fast Recovery.
    if !r.in_congestion_recovery(time_sent) {
        // Upon entering Fast Recovery.
        bbr_enter_recovery(r, now);
    }
}

fn collapse_cwnd(r: &mut Recovery) {
    r.bbr_state.prior_cwnd = per_ack::bbr_save_cwnd(r);

    reno::collapse_cwnd(r);
}

fn checkpoint(_r: &mut Recovery) {}

fn rollback(_r: &mut Recovery) -> bool {
    false
}

fn has_custom_pacing() -> bool {
    true
}

fn debug_fmt(r: &Recovery, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    let bbr = &r.bbr_state;

    write!(
         f,
         "bbr={{ state={:?} btlbw={} rtprop={:?} pacing_rate={} pacing_gain={} cwnd_gain={} target_cwnd={} send_quantum={} filled_pipe={} round_count={} }}",
         bbr.state, bbr.btlbw, bbr.rtprop, bbr.pacing_rate, bbr.pacing_gain, bbr.cwnd_gain, bbr.target_cwnd, r.send_quantum(), bbr.filled_pipe, bbr.round_count
    )
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::recovery;

    #[test]
    fn bbr_init() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);

        // on_init() is called in Connection::new(), so it need to be
        // called manually here.
        r.on_init();

        assert_eq!(r.cwnd(), r.max_datagram_size * INITIAL_WINDOW_PACKETS);
        assert_eq!(r.bytes_in_flight, 0);

        assert_eq!(r.bbr_state.state, BBRStateMachine::Startup);
    }

    #[test]
    fn bbr_send() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();

        r.on_init();
        r.on_packet_sent_cc(1000, now);

        assert_eq!(r.bytes_in_flight, 1000);
    }

    #[test]
    fn bbr_startup() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let mss = r.max_datagram_size;

        r.on_init();

        // Send 5 packets.
        for pn in 0..5 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: 0,
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );
        }

        let rtt = Duration::from_millis(50);
        let now = now + rtt;
        let cwnd_prev = r.cwnd();

        let mut acked = ranges::RangeSet::default();
        acked.insert(0..5);

        assert_eq!(
            r.on_ack_received(
                &acked,
                25,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            ),
            Ok((0, 0)),
        );

        assert_eq!(r.bbr_state.state, BBRStateMachine::Startup);
        assert_eq!(r.cwnd(), cwnd_prev + mss * 5);
        assert_eq!(r.bytes_in_flight, 0);
        assert_eq!(
            r.delivery_rate(),
            ((mss * 5) as f64 / rtt.as_secs_f64()) as u64
        );
        assert_eq!(r.bbr_state.btlbw, r.delivery_rate());
    }

    #[test]
    fn bbr_congestion_event() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let mss = r.max_datagram_size;

        r.on_init();

        // Send 5 packets.
        for pn in 0..5 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: 0,
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );
        }

        let rtt = Duration::from_millis(50);
        let now = now + rtt;

        // Make a packet loss to trigger a congestion event.
        let mut acked = ranges::RangeSet::default();
        acked.insert(4..5);

        // 2 acked, 2 x MSS lost.
        assert_eq!(
            r.on_ack_received(
                &acked,
                25,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            ),
            Ok((2, 2400)),
        );

        // Sent: 0, 1, 2, 3, 4, Acked 4.
        assert_eq!(r.cwnd(), mss * 4);
        // Stil in flight: 2, 3.
        assert_eq!(r.bytes_in_flight, mss * 2);
    }

    #[test]
    fn bbr_drain() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let mss = r.max_datagram_size;

        r.on_init();

        let mut pn = 0;

        // Stop right before filled_pipe=true.
        for _ in 0..3 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: r.delivery_rate.delivered(),
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );

            pn += 1;

            let rtt = Duration::from_millis(50);

            let now = now + rtt;

            let mut acked = ranges::RangeSet::default();
            acked.insert(0..pn);

            assert_eq!(
                r.on_ack_received(
                    &acked,
                    25,
                    packet::Epoch::Application,
                    HandshakeStatus::default(),
                    now,
                    "",
                ),
                Ok((0, 0)),
            );
        }

        // Stop at right before filled_pipe=true.
        for _ in 0..5 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: r.delivery_rate.delivered(),
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );

            pn += 1;
        }

        let rtt = Duration::from_millis(50);
        let now = now + rtt;

        let mut acked = ranges::RangeSet::default();

        // We sent 5 packets, but ack only one, to stay
        // in Drain state.
        acked.insert(0..pn - 4);

        assert_eq!(
            r.on_ack_received(
                &acked,
                25,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            ),
            Ok((0, 0)),
        );

        // Now we are in Drain state.
        assert_eq!(r.bbr_state.filled_pipe, true);
        assert_eq!(r.bbr_state.state, BBRStateMachine::Drain);
        assert!(r.bbr_state.pacing_gain < 1.0);
    }

    #[test]
    fn bbr_probe_bw() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let mss = r.max_datagram_size;

        r.on_init();

        let mut pn = 0;

        // At 4th roundtrip, filled_pipe=true and switch to Drain,
        // but move to ProbeBW immediately because bytes_in_flight is
        // smaller than BBRInFlight(1).
        for _ in 0..4 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: r.delivery_rate.delivered(),
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );

            pn += 1;

            let rtt = Duration::from_millis(50);
            let now = now + rtt;

            let mut acked = ranges::RangeSet::default();
            acked.insert(0..pn);

            assert_eq!(
                r.on_ack_received(
                    &acked,
                    25,
                    packet::Epoch::Application,
                    HandshakeStatus::default(),
                    now,
                    "",
                ),
                Ok((0, 0)),
            );
        }

        // Now we are in ProbeBW state.
        assert_eq!(r.bbr_state.filled_pipe, true);
        assert_eq!(r.bbr_state.state, BBRStateMachine::ProbeBW);

        // In the first ProbeBW cycle, pacing_gain should be >= 1.0.
        assert!(r.bbr_state.pacing_gain >= 1.0);
    }

    #[test]
    fn bbr_probe_rtt() {
        let mut cfg = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
        cfg.set_cc_algorithm(recovery::CongestionControlAlgorithm::BBR);

        let mut r = Recovery::new(&cfg);
        let now = Instant::now();
        let mss = r.max_datagram_size;

        r.on_init();

        let mut pn = 0;

        // At 4th roundtrip, filled_pipe=true and switch to Drain,
        // but move to ProbeBW immediately because bytes_in_flight is
        // smaller than BBRInFlight(1).
        for _ in 0..4 {
            let pkt = Sent {
                pkt_num: pn,
                frames: vec![],
                time_sent: now,
                time_acked: None,
                time_lost: None,
                size: mss,
                ack_eliciting: true,
                in_flight: true,
                delivered: r.delivery_rate.delivered(),
                delivered_time: now,
                first_sent_time: now,
                is_app_limited: false,
                has_data: false,
            };

            r.on_packet_sent(
                pkt,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            );

            pn += 1;

            let rtt = Duration::from_millis(50);
            let now = now + rtt;

            let mut acked = ranges::RangeSet::default();
            acked.insert(0..pn);

            assert_eq!(
                r.on_ack_received(
                    &acked,
                    25,
                    packet::Epoch::Application,
                    HandshakeStatus::default(),
                    now,
                    "",
                ),
                Ok((0, 0)),
            );
        }

        // Now we are in ProbeBW state.
        assert_eq!(r.bbr_state.state, BBRStateMachine::ProbeBW);

        // After RTPROP_FILTER_LEN (10s), switch to ProbeRTT.
        let now = now + RTPROP_FILTER_LEN;

        let pkt = Sent {
            pkt_num: pn,
            frames: vec![],
            time_sent: now,
            time_acked: None,
            time_lost: None,
            size: mss,
            ack_eliciting: true,
            in_flight: true,
            delivered: r.delivery_rate.delivered(),
            delivered_time: now,
            first_sent_time: now,
            is_app_limited: false,
            has_data: false,
        };

        r.on_packet_sent(
            pkt,
            packet::Epoch::Application,
            HandshakeStatus::default(),
            now,
            "",
        );

        pn += 1;

        // Don't update rtprop by giving larger rtt than before.
        // If rtprop is updated, rtprop expiry check is reset.
        let rtt = Duration::from_millis(100);
        let now = now + rtt;

        let mut acked = ranges::RangeSet::default();
        acked.insert(0..pn);

        assert_eq!(
            r.on_ack_received(
                &acked,
                25,
                packet::Epoch::Application,
                HandshakeStatus::default(),
                now,
                "",
            ),
            Ok((0, 0)),
        );

        assert_eq!(r.bbr_state.state, BBRStateMachine::ProbeRTT);
        assert_eq!(r.bbr_state.pacing_gain, 1.0);
    }
}

mod init;
mod pacing;
mod per_ack;
mod per_transmit;


text:
<?php

/* 访问控制 */
defined('IN_ECTOUCH') or die('Deny Access');

class WechatController extends CommonController {}


text:
package com.esri.gpt.server.openls.provider.util;

/**
 *
Title:

 *
Description:

 *
Copyright: Copyright (c) 2005

 *
Company:

 * @author not attributable
 * @version 1.0
 */

public class POIInfo {

  String _name;
  String _value;

  public POIInfo() {
  }

  public void setName(String name){
    _name = name;
  }
  public String getName(){
    return _name;
  }
  public void setValue(String name){
    _value = name;
  }
  public String getValue(){
    return _value;
  }
}


text: <slot></slot>


text:
package org.jclouds.azurecompute.domain;

import com.google.auto.value.AutoValue;
import java.net.URL;

@AutoValue
public abstract class StorageServiceKeys {

   public enum KeyType {

      Primary,
      Secondary;

   }

   StorageServiceKeys() {
   } // For AutoValue only!

   /**
    * The Service Management API request URI used to perform Get Storage Account Properties requests against the storage
    * account.
    */
   public abstract URL url();

   /**
    * The primary access key for the storage account.
    */
   public abstract String primary();

   /**
    * The secondary access key for the storage account.
    */
   public abstract String secondary();

   public static StorageServiceKeys create(final URL url, final String primary, final String secondary) {
      return new AutoValue_StorageServiceKeys(url, primary, secondary);
   }
}


text:
<?php

namespace Mschlueter\Backend\Exceptions;

use Illuminate\Auth\AuthenticationException;

class Handler extends \App\Exceptions\Handler {
    /**
     * Convert an authentication exception into an unauthenticated response.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Illuminate\Auth\AuthenticationException $exception
     *
     * @return \Illuminate\Http\Response
     */
    protected function unauthenticated($request, AuthenticationException $exception) {
        if($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        return redirect()->guest(route('backend.login'));
    }
}


text:
Retryprocessor is a [swarrot](https://github.com/swarrot/swarrot) processor.
Its goal is to re-published messages in broker when an error occurred.

## Configuration

|Key                      |Default|Description                                                                  |
|:-----------------------:|:-----:|-----------------------------------------------------------------------------|
|retry_key_pattern        |       |[MANDATORY] The pattern to use to construct routing key (ie: `key_%attempt%`)|
|retry_attempts           |3      |The number of attempts before raising an exception.                          |
|retry_log_levels_map     |[]     |Map of classes to a log level when retry. (Warning by default)               |
|retry_fail_log_levels_map|[]     |Map of classes to a log level when all retries failed. (Warning by default)  |

## How it works

When your processor throw an exception (= failed to process a message), the
Retry Processor will catch it, and republish the message in a given exchange
with the `retry_key_pattern`.

For example if the given `MessagePublisherInterface` is configured to publish
in the exchange named `retry` and if the `retry_key_pattern` is
`key_%attempts%`, when an exception is thrown, the `RetryProcessor` will
publish a new message (similar to the first one) in the exchange `retry` with
the routing_key `key_1`.

## Real example

Let's say you want to consume a queue named `mail`. You would like to have 3
retries if the mail is not sent correctly. The first retry 30 seconds after,
the second 3 minutes and the last one half an hour.

First, let's create the simple mail workflow.

* Create an exchange `mail` (type: `direct`)
* Create an queue `mail`
* Bind the exchange `mail` to the queue `mail` with routing_key `mail`

Now, to handle errors, let's say we republish all errors to an exchange
`retry`. For our mail, the `retry_key_pattern` will be `mail_retry_%attempts%`.
Here is what we need to have the first retry working:

* Create an exchange `retry` (type: `direct`)
* Create a queue `mail_retry_1` with following arguments: `x-message-ttl:
  30000` (our 30 seconds), `x-dead-letter-exchange: mail` (the first exchange
  we created), `x-dead-letter-routing-key: mail`
* Bind the exchange `retry` to the queue `mail_retry_1` with routing_key
  `mail_retry_1`

Once this configuration is done, when an exception is thrown, the
RetryProcessor will publish a new message (similar to the first one) to the
exchange `retry` with the routing_key `mail_retry_1`. This message will be
route to the queue `mail_retry_1`. As there is a ttl, 30 seconds after its
arrival, the message will be sent to the configured dead-letter exchange with
the given dead-letter routing-key. In our case the message will go into the
exchange mail with the routing key mail. Due to our first configuration, it
will finish in the queue mail which is consumed by our consumer.

Of course if we want more than only one retry, we can create new queues
`mail_retry_X` with the same configuration. The `RetryProcessor` will use the
`swarrot_retry_attempts` key in the message headers to determine if the message
must be retried or not.


text:
#ifndef DL_HASHTABLE_HPP
#define DL_HASHTABLE_HPP

#include <ndb_global.h>
#include "ArrayPool.hpp"

/**
 * DLHashTable implements a hashtable using chaining
 *   (with a double linked list)
 *
 * The entries in the hashtable must have the following methods:
 *  -# bool equal(const class T &) const;
 *     Which should return equal if the to objects have the same key
 *  -# Uint32 hashValue() const;
 *     Which should return a 32 bit hashvalue
 */
template <typename P, typename T, typename U = T>
class DLHashTableImpl
{
public:
  DLHashTableImpl(P & thePool);
  ~DLHashTableImpl();

  /**
   * Set the no of bucket in the hashtable
   *
   * Note, can currently only be called once
   */
  bool setSize(Uint32 noOfElements);

  /**
   * Seize element from pool - return i
   *
   * Note *must* be added using add (even before hash.release)
   *             or be released using pool
   */
  bool seize(Ptr<T> &);

  /**
   * Add an object to the hashtable
   */
  void add(Ptr<T> &);

  /**
   * Find element key in hashtable update Ptr (i & p)
   *   (using key.equal(...))
   * @return true if found and false otherwise
   */
  bool find(Ptr<T> &, const T & key) const;

  /**
   * Update i & p value according to i
   */
  void getPtr(Ptr<T> &, Uint32 i) const;

  /**
   * Get element using ptr.i (update ptr.p)
   */
  void getPtr(Ptr<T> &) const;

  /**
   * Get P value for i
   */
  T * getPtr(Uint32 i) const;

  /**
   * Remove element (and set Ptr to removed element)
   * Note does not return to pool
   */
  void remove(Ptr<T> &, const T & key);

  /**
   * Remove element
   * Note does not return to pool
   */
  void remove(Uint32 i);

  /**
   * Remove element
   * Note does not return to pool
   */
  void remove(Ptr<T> &);

  /**
   * Remove all elements, but dont return them to pool
   */
  void removeAll();

  /**
   * Remove element and return to pool
   */
  void release(Uint32 i);

  /**
   * Remove element and return to pool
   */
  void release(Ptr<T> &);

  class Iterator {
  public:
    Ptr<T> curr;
    Uint32 bucket;
    inline bool isNull() const { return curr.isNull();}
    inline void setNull() { curr.setNull(); }
  };

  /**
   * Sets curr.p according to curr.i
   */
  void getPtr(Iterator & iter) const ;

  /**
   * First element in bucket
   */
  bool first(Iterator & iter) const;

  /**
   * Next Element
   *
   * param iter - A "fully set" iterator
   */
  bool next(Iterator & iter) const;

  /**
   * Get next element starting from bucket
   *
   * @param bucket - Which bucket to start from
   * @param iter - An "uninitialized" iterator
   */
  bool next(Uint32 bucket, Iterator & iter) const;

private:
  Uint32 mask;
  Uint32 * hashValues;
  P & thePool;
};

template <typename P, typename T, typename U>
inline
DLHashTableImpl
::DLHashTableImpl(P & _pool)
  : thePool(_pool)
{
  mask = 0;
  hashValues = 0;
}

template <typename P, typename T, typename U>
inline
DLHashTableImpl
::~DLHashTableImpl()
{
  if(hashValues != 0)
    delete [] hashValues;
}

template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::setSize(Uint32 size)
{
  Uint32 i = 1;
  while(i < size) i *= 2;

  if(mask == (i - 1))
  {
    /**
     * The size is already set to size
     */
    return true;
  }

  if(mask != 0)
  {
    /**
     * The mask is already set
     */
    return false;
  }

  mask = (i - 1);
  hashValues = new Uint32[i];
  for(Uint32 j = 0; j<i; j++)
    hashValues[j] = RNIL;

  return true;
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::add(Ptr<T> & obj)
{
  const Uint32 hv = obj.p->hashValue() & mask;
  const Uint32 i  = hashValues[hv];

  if(i == RNIL)
  {
    hashValues[hv] = obj.i;
    obj.p->U::nextHash = RNIL;
    obj.p->U::prevHash = RNIL;
  }
  else
  {
    T * tmp = thePool.getPtr(i);
    tmp->U::prevHash = obj.i;
    obj.p->U::nextHash = i;
    obj.p->U::prevHash = RNIL;

    hashValues[hv] = obj.i;
  }
}

/**
 * First element
 */
template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::first(Iterator & iter) const
{
  Uint32 i = 0;
  while(i <= mask && hashValues[i] == RNIL) i++;
  if(i <= mask)
  {
    iter.bucket = i;
    iter.curr.i = hashValues[i];
    iter.curr.p = thePool.getPtr(iter.curr.i);
    return true;
  }
  else
  {
    iter.curr.i = RNIL;
  }
  return false;
}

template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::next(Iterator & iter) const
{
  if(iter.curr.p->U::nextHash == RNIL)
  {
    Uint32 i = iter.bucket + 1;
    while(i <= mask && hashValues[i] == RNIL) i++;
    if(i <= mask)
    {
      iter.bucket = i;
      iter.curr.i = hashValues[i];
      iter.curr.p = thePool.getPtr(iter.curr.i);
      return true;
    }
    else
    {
      iter.curr.i = RNIL;
      return false;
    }
  }

  iter.curr.i = iter.curr.p->U::nextHash;
  iter.curr.p = thePool.getPtr(iter.curr.i);
  return true;
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::remove(Ptr<T> & ptr, const T & key)
{
  const Uint32 hv = key.hashValue() & mask;

  Uint32 i;
  T * p;
  Ptr<T> prev;
  LINT_INIT(prev.p);
  prev.i = RNIL;

  i = hashValues[hv];
  while(i != RNIL)
  {
    p = thePool.getPtr(i);
    if(key.equal(* p))
    {
      const Uint32 next = p->U::nextHash;
      if(prev.i == RNIL)
      {
	hashValues[hv] = next;
      }
      else
      {
	prev.p->U::nextHash = next;
      }

      if(next != RNIL)
      {
	T * nextP = thePool.getPtr(next);
	nextP->U::prevHash = prev.i;
      }

      ptr.i = i;
      ptr.p = p;
      return;
    }
    prev.p = p;
    prev.i = i;
    i = p->U::nextHash;
  }
  ptr.i = RNIL;
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::remove(Uint32 i)
{
  Ptr<T> tmp;
  tmp.i = i;
  tmp.p = thePool.getPtr(i);
  remove(tmp);
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::release(Uint32 i)
{
  Ptr<T> tmp;
  tmp.i = i;
  tmp.p = thePool.getPtr(i);
  release(tmp);
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::remove(Ptr<T> & ptr)
{
  const Uint32 next = ptr.p->U::nextHash;
  const Uint32 prev = ptr.p->U::prevHash;

  if(prev != RNIL)
  {
    T * prevP = thePool.getPtr(prev);
    prevP->U::nextHash = next;
  }
  else
  {
    const Uint32 hv = ptr.p->hashValue() & mask;
    if (hashValues[hv] == ptr.i)
    {
      hashValues[hv] = next;
    }
    else
    {
      // Will add assert in 5.1
    }
  }

  if(next != RNIL)
  {
    T * nextP = thePool.getPtr(next);
    nextP->U::prevHash = prev;
  }
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::release(Ptr<T> & ptr)
{
  const Uint32 next = ptr.p->U::nextHash;
  const Uint32 prev = ptr.p->U::prevHash;

  if(prev != RNIL)
  {
    T * prevP = thePool.getPtr(prev);
    prevP->U::nextHash = next;
  }
  else
  {
    const Uint32 hv = ptr.p->hashValue() & mask;
    if (hashValues[hv] == ptr.i)
    {
      hashValues[hv] = next;
    }
    else
    {
      // Will add assert in 5.1
    }
  }

  if(next != RNIL)
  {
    T * nextP = thePool.getPtr(next);
    nextP->U::prevHash = prev;
  }

  thePool.release(ptr);
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::removeAll()
{
  for(Uint32 i = 0; i<=mask; i++)
    hashValues[i] = RNIL;
}

template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::next(Uint32 bucket, Iterator & iter) const
{
  while (bucket <= mask && hashValues[bucket] == RNIL)
    bucket++;

  if (bucket > mask)
  {
    iter.bucket = bucket;
    iter.curr.i = RNIL;
    return false;
  }

  iter.bucket = bucket;
  iter.curr.i = hashValues[bucket];
  iter.curr.p = thePool.getPtr(iter.curr.i);
  return true;
}

template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::seize(Ptr<T> & ptr)
{
  if(thePool.seize(ptr)){
    ptr.p->U::nextHash = ptr.p->U::prevHash = RNIL;
    return true;
  }
  return false;
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::getPtr(Ptr<T> & ptr, Uint32 i) const
{
  ptr.i = i;
  ptr.p = thePool.getPtr(i);
}

template <typename P, typename T, typename U>
inline
void
DLHashTableImpl
::getPtr(Ptr<T> & ptr) const
{
  thePool.getPtr(ptr);
}

template <typename P, typename T, typename U>
inline
T *
DLHashTableImpl
::getPtr(Uint32 i) const
{
  return thePool.getPtr(i);
}

template <typename P, typename T, typename U>
inline
bool
DLHashTableImpl
::find(Ptr<T> & ptr, const T & key) const
{
  const Uint32 hv = key.hashValue() & mask;

  Uint32 i;
  T * p;

  i = hashValues[hv];
  while(i != RNIL)
  {
    p = thePool.getPtr(i);
    if(key.equal(* p))
    {
      ptr.i = i;
      ptr.p = p;
      return true;
    }
    i = p->U::nextHash;
  }
  ptr.i = RNIL;
  ptr.p = NULL;
  return false;
}

// Specializations

template <typename T, typename U = T>
class DLHashTable : public DLHashTableImpl<ArrayPool<T>, T, U>
{
public:
  DLHashTable(ArrayPool<T> & p) : DLHashTableImpl<ArrayPool<T>, T, U>(p) {}
};

#endif


text:
package com.yassirh.digitalocean.ui;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ListFragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import com.yassirh.digitalocean.R;
import com.yassirh.digitalocean.model.Region;
import com.yassirh.digitalocean.service.RegionService;

public class RegionsFragment extends ListFragment implements Updatable, SwipeRefreshLayout.OnRefreshListener{

	RegionAdapter mRegionAdapter;
	List<Region> mRegions = new ArrayList<Region>();
	RegionService mRegionService;
	private SwipeRefreshLayout mSwipeRefreshLayout;
	private Handler mHandler = new Handler();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		mRegionService = new RegionService(getActivity());
		update(this.getActivity());
		View layout = inflater.inflate(R.layout.fragment_regions, container, false);
		mSwipeRefreshLayout = (SwipeRefreshLayout) layout.findViewById(R.id.swipe_container);
		mSwipeRefreshLayout.setOnRefreshListener(this);
		mSwipeRefreshLayout.setColorScheme(R.color.blue_bright,
	            R.color.green_light,
	            R.color.orange_light,
	            R.color.red_light);
		return layout;
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		final ListView listView = getListView();
		listView.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				boolean enable = false;
		        if(listView != null && listView.getChildCount() > 0){
		            boolean firstItemVisible = listView.getFirstVisiblePosition() == 0;
		            boolean topOfFirstItemVisible = listView.getChildAt(0).getTop() == 0;
		            enable = firstItemVisible && topOfFirstItemVisible;
		        }
			    mSwipeRefreshLayout.setEnabled(enable);
			}
		});
		registerForContextMenu(listView);
	}

	@Override
	public void update(Context context) {
		mRegions = mRegionService.getAllRegionsOrderedByName();
		mRegionAdapter = new RegionAdapter(this.getActivity(), mRegions);
		setListAdapter(mRegionAdapter);
	}

	@Override
	public void onRefresh() {
		mRegionService.getAllRegionsFromAPI(true);
		mHandler.post(refreshing);
	}

	private final Runnable refreshing = new Runnable(){
	    public void run(){
	        try {
	        	if(mRegionService.isRefreshing()){
	        		mHandler.postDelayed(this, 1000);
	        	}else{
	        		mSwipeRefreshLayout.setRefreshing(false);
	        	}
	        }
	        catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
	};
}


text:
namespace Void
{
    namespace System
    {
        // VWindowExtension
        //----------------------------------------------------------------------------------------------------
        struct VWindowExtension
        {
        public:
            //----------------------------------------------------------------------------------------------------
            static VWindowExtension* Instance();

        protected:
            //----------------------------------------------------------------------------------------------------
            VWindowExtension() = default;
            virtual ~VWindowExtension() = default;

        public:
            //----------------------------------------------------------------------------------------------------
            virtual bool Extend(VWindowPointer _window) { return false; };

            // Graphics
            //----------------------------------------------------------------------------------------------------
            virtual bool MakeCurrentContext(VWindowPointer _window) { return false; };
            virtual bool ClearCurrentContext() { return false; };
            virtual bool FlushBuffer() { return false; };
            virtual bool SetSwapInterval(int _interval) { return false; };

        protected:
            //----------------------------------------------------------------------------------------------------
        };

        // VWindowExtensionPointer
        //----------------------------------------------------------------------------------------------------
        typedef VSharePointer<VWindowExtension> VWindowExtensionPointer;
    }
}

#endif