class_ShippingCompany.php

Go to the documentation of this file.
00001 <?php
00024 class ShippingCompany extends BaseSimulator implements Customer, ContractPartner {
00028         private $companyName     = "Namenlose Reederei";
00029 
00033         private $shortName       = "";
00034 
00038         private $founderInstance = null;
00039 
00043         private $hqInstance      = null;
00044 
00048         private $employeeList    = null;
00049 
00053         private $shipyardList   = null;
00054 
00058         private $ownedShips      = null;
00059 
00063         private $contractList    = null;
00064 
00065         // Exception constants
00066         const EXCEPTION_USER_OWNS_NO_COMPANY = 0x200;
00067 
00073         protected function __construct () {
00074                 // Call parent constructor
00075                 parent::__construct(__CLASS__);
00076         }
00077 
00086         public final static function createShippingCompany (ManageableAccount $userInstance) {
00087                 // Get new instance
00088                 $companyInstance = new ShippingCompany();
00089 
00090                 // Does the given user owns a company?
00091                 if ($companyInstance->ifUserParticipatesInCompany($userInstance)) {
00092                         // Then do some nasty caching here but don't throw an exception
00093                         // because then you will hurt our web helpers... :/
00094                         $companyInstance->partialStub("Don&#39;t throw exceptions here.");
00095                 } // END - if
00096 
00097                 // Init all lists
00098                 $companyInstance->initCompanyLists();
00099 
00100                 // Return instance
00101                 return $companyInstance;
00102         }
00103 
00110         protected function ifUserParticipatesInCompany (ManageableAccount $userInstance)  {
00111                 // By default no user owns any company... ;)
00112                 $participates = false;
00113 
00114                 // Get a company database wrapper class
00115                 $wrapperInstance = ObjectFactory::createObjectByConfiguredName('company_db_wrapper_class', array($this));
00116 
00117                 // Ask the wrapper if this user participates
00118                 $participates = $wrapperInstance->ifUserParticipatesInCompany($userInstance);
00119 
00120                 // Get the result instance
00121                 $resultInstance = $wrapperInstance->getResultInstance();
00122 
00123                 // Caches the result instance here, if set (we don't the wrapper anymore!)
00124                 if ($resultInstance instanceof SearchableResult) {
00125                         // Set the result instance
00126                         $this->setResultInstance($resultInstance);
00127                 } // END - if
00128 
00129                 // Return result
00130                 return $participates;
00131         }
00132 
00139         public function ifUserIsFounder () {
00140                 // Default is not the founder
00141                 $isFounder = false;
00142 
00143                 // Get result instance
00144                 $resultInstance = $this->getResultInstance();
00145 
00146                 // Is it set?
00147                 if ($resultInstance instanceof SearchableResult) {
00148                         // Result found so analyse it
00149                         $this->partialStub("Check if user is company founder.");
00150                 } // END - if
00151 
00152                 // Return result
00153                 return $isFounder;
00154         }
00155 
00162         public function ifUserIsOwner () {
00163                 // Default is not the owner
00164                 $isOwner = false;
00165 
00166                 // Get result instance
00167                 $resultInstance = $this->getResultInstance();
00168 
00169                 // Is it set?
00170                 if ($resultInstance instanceof SearchableResult) {
00171                         // Result found so analyse it
00172                         $this->partialStub("Check if user is company owner.");
00173                 } // END - if
00174 
00175                 // Return result
00176                 return $isOwner;
00177         }
00178 
00184         public function ifUserIsEmployee () {
00185                 // Default is no employee
00186                 $isEmployee = false;
00187 
00188                 // Get result instance
00189                 $resultInstance = $this->getResultInstance();
00190 
00191                 // Is it set?
00192                 if ($resultInstance instanceof SearchableResult) {
00193                         // Result found so he is employee
00194                         $isEmployee = true;
00195                 } // END - if
00196 
00197                 // Return result
00198                 return $isEmployee;
00199         }
00200 
00201         //------------------------------------------------------------------------------\
00202         // Below here is very old code which needs to be translated and changed heavily |
00203         //------------------------------------------------------------------------------/
00204 
00211         protected function initCompanyLists () {
00212                 // Employees
00213                 $this->employeeList = new FrameworkArrayObject("FakedEmployeeList");
00214 
00215                 // Ship yards
00216                 $this->shipyardList = new FrameworkArrayObject("FakedShipyardList");
00217 
00218                 // Contracts
00219                 $this->contractList = new FrameworkArrayObject("FakedContractList");
00220         }
00221 
00222         // Setter-Methode fuer Firmennamen
00223         public final function setCompanyName ($companyName) {
00224                 $this->companyName = (string) $companyName;
00225         }
00226 
00227         // Getter-Methode fuer Firmennamen
00228         public final function getCompanyName () {
00229                 return $this->companyName;
00230         }
00231 
00232         // Setter-Methode fuer Firmensitz
00233         public final function setHQInstance (Harbor $hqInstance) {
00234                 $this->hqInstance = $hqInstance;
00235         }
00236 
00237         // Kuerzel setzen
00238         private function initShortName () {
00239                 // Mindestens eine Leerstelle?
00240                 $dummy = explode(" ", $this->getCompanyName());
00241                 foreach ($dummy as $part) {
00242                         $this->shortName .= substr($part, 0, 1);
00243                 } // END - if
00244         }
00245 
00246         // Reedereien Werften bauen lassen
00247         public function createShipyardInHarbor($shipyardName, Harbor $harborInstance) {
00248                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> baut im <strong>%s</strong> eine Werft <strong>%s</strong>.",
00249                         __CLASS__,
00250                         __LINE__,
00251                         $this->getCompanyName(),
00252                         $harborInstance->getHarborName(),
00253                         $shipyardName
00254                 ));
00255 
00256                 // Wird im HQ gebaut?
00257                 if ($this->hqInstance->equals($harborInstance)) {
00258                         // Die neue Werft wird im HQ gebaut!
00259                         $this->hqInstance->addNewShipyardNotify($shipyardName, $this);
00260                         // Die Werft drueber in Kenntnis setzen, welcher Reederei sie angehoert
00261                 } else {
00262                         // Ausserhalb des Heimathafens soll eine Werft gebaut werden
00263                         $harborInstance->addNewShipyardNotify($shipyardName, $this);
00264                 }
00265         }
00266 
00267         // Setter fuer Reederei-Gruender
00268         public final function setCompanyFounder(CompanyEmployee $founderInstance) {
00269                 $this->founderInstance = $founderInstance;
00270         }
00271 
00272         // Getter for founder instance
00273         public final function getFounderInstance () {
00274                 return $this->founderInstance;
00275         }
00276 
00277         // Neue(n) Angestellte(n) in Angestellten-Liste aufnehmen
00278         public function addNewEmployee (SimulatorPersonell $employeeInstance) {
00279                 $this->employeeList->append($employeeInstance);
00280         }
00281 
00282         // Neue Werft in Liste aufnehmen
00283         public function addNewShipyard (Shipyard $shipyardInstance) {
00284                 $this->shipyardList->append($shipyardInstance);
00285         }
00286 
00287         // Neue Mitarbeiter per Zufall einstellen/rekrutieren
00288         public function recruitRandomEmployees($amount, SimulatorPersonell $personellInstance) {
00289                 // Anzahl Mitarbeiter absichern
00290                 $amount = (int) $amount;
00291 
00292                 // Debug-Meldung ausgeben
00293                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt per Zufall <strong>%d</strong> neue Mitarbeiter ein.",
00294                         __CLASS__,
00295                         __LINE__,
00296                         $this->getCompanyName(),
00297                         $amount
00298                 ));
00299 
00300                 // Gesamtanzahl verfuegbarer Erwerbsloser holen
00301                 $totalUnemployed = $personellInstance->getAllUnemployed();
00302 
00303                 // Existiert die gewuenschte Anzahl freier Arbeiter? (doppelt geht derzeit nicht)
00304                 if ($totalUnemployed < $amount) {
00305                         // Reichte nicht aus!
00306                         throw new ToMuchEmployeesException(array($amount, $personellInstance->getAllUnemployed()), self::EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES);
00307                 } // END - if
00308 
00309                 // Get list for all unemployed people
00310                 $list = $personellInstance->getSpecialPersonellList(false); // Should be cached
00311 
00312                 // Get iterator of the list
00313                 $iterator = $list->getIterator();
00314 
00315                 // Get the requested amount of personell
00316                 for ($idx = 0; $idx < $amount; $idx++) {
00317                         $employee = null;
00318                         // Is this personl unemployed?
00319                         while (is_null($employee) || $employee->isEmployed()) {
00320                                 // Generate random number
00321                                 $pos = mt_rand(0, ($totalUnemployed - 1)); // Don't remove the -1 here:
00322                                 // E.g. 100 entries means latest position is 99...
00323 
00324                                 // Seek for the position
00325                                 $iterator->seek($pos);
00326 
00327                                 // Is the current position valid?
00328                                 if ($iterator->valid() === false) {
00329                                         // Should normally not happen... :(
00330                                         throw new StructuresOutOfBoundsException($idx, self::EXCEPTION_INDEX_OUT_OF_BOUNDS);
00331                                 } // END - if
00332 
00333                                 // Get current element
00334                                 $employee = $iterator->current();
00335                         } // END - while
00336 
00337                         // A dummy just for the description and real class
00338                         $dummy = CompanyEmployee::createCompanyEmployee("", "", "M", 1970, 1, 1, $employee->isMarried(), 0);
00339 
00340                         // Make this person employed and give him some money to work
00341                         $employee->setEmployed(true);
00342                         $employee->setRealClass($dummy->__toString());
00343                         $employee->increaseSalary((mt_rand(7, 14) * 100)); // Are 700 to 1400 EUR for the begin okay?
00344 
00345                         // Debug message
00346                         if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt den/die Angestellte(n) <strong>%s %s</strong> ein.",
00347                                 __CLASS__,
00348                                 __LINE__,
00349                                 $this->getCompanyName(),
00350                                 $employee->getSurname(),
00351                                 $employee->getFamily()
00352                         ));
00353 
00354                         // Add this employee
00355                         $this->addNewEmployee($employee);
00356                 } // End - for
00357 
00358                 // Cache resetten
00359                 $personellInstance->resetCache();
00360 
00361                 // Debug-Meldung ausgeben
00362                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat per Zufall <strong>%d</strong> neue Mitarbeiter eingestellt.",
00363                         __CLASS__,
00364                         __LINE__,
00365                         $this->getCompanyName(),
00366                         $amount
00367                 ));
00368         } // End - method
00369 
00370         // Distribute all personells on all shipyards
00371         public function distributeAllPersonellOnShipyards () {
00372                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> verteilt alle ihre <strong>%d</strong> Mitarbeiter auf alle <strong>%d</strong> Werft(en).",
00373                         __CLASS__,
00374                         __LINE__,
00375                         $this->getCompanyName(),
00376                         $this->getTotalEmployee(),
00377                         $this->getTotalShipyards()
00378                 ));
00379 
00380                 // Do we have some shipyards?
00381                 if (is_null($this->shipyardList)) {
00382                         // No shipyards created
00383                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
00384                 }
00385 
00386                 // Get iterator for shipyards
00387                 $shipyardIter = $this->shipyardList->getIterator();
00388 
00389                 // Iterate through all employees
00390                 for ($idx = $this->employeeList->getIterator(); $idx->valid(); $idx->next()) {
00391                         // Is the shipyard iterator still okay?
00392                         if ($shipyardIter->valid() === false) {
00393                                 // Rewind to first position
00394                                 $shipyardIter->seek(0);
00395                         } // END - if
00396 
00397                         // Get Shipyard object
00398                         $shipyard = $shipyardIter->current();
00399 
00400                         // Is this a Shipyard object?
00401                         if (is_null($shipyard)) {
00402                                 // No class returned
00403                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
00404                         } elseif (!is_object($shipyard)) {
00405                                 // Not an object! ;-(
00406                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
00407                         } elseif ($shipyard->isClass("Shipyard") === false) {
00408                                 // Nope, so throw exception
00409                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
00410                         }
00411 
00412                         // Add employee to the shipyard
00413                         $shipyard->addNewPersonell($idx->current());
00414 
00415                         // Continue to next shipyard
00416                         $shipyardIter->next();
00417                 }
00418         }
00419 
00420         // Getter for total employees
00421         public final function getTotalEmployee () {
00422                 // Count all...
00423                 $total = $this->employeeList->count();
00424 
00425                 // Debug message
00426                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Mitarbeiter.",
00427                         __CLASS__,
00428                         __LINE__,
00429                         $this->getCompanyName(),
00430                         $total
00431                 ));
00432 
00433                 // Return amount
00434                 return $total;
00435         }
00436 
00437         // Getter for total shipyards
00438         public final function getTotalShipyards () {
00439                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] F&uuml;r die Reederei <strong>%s</strong> werden die Anzahl der Werften in allen H&auml;fen ermittelt.",
00440                         __CLASS__,
00441                         __LINE__,
00442                         $this->getCompanyName()
00443                 ));
00444 
00445                 // Do we have some shipyards?
00446                 if (is_null($this->shipyardList)) {
00447                         // No shipyards created
00448                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
00449                 }
00450 
00451                 // Get iterator
00452                 $total = $this->shipyardList->count();
00453 
00454                 // Debug message
00455                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Werft(en).",
00456                         __CLASS__,
00457                         __LINE__,
00458                         $this->getCompanyName(),
00459                         $total
00460                 ));
00461 
00462                 // Return amount
00463                 return $total;
00464         }
00465 
00466         // Add a ship type (class) to all shipyards
00467         public function addShipTypeToAllShipyards ($shipType) {
00468                 // Secure strings
00469                 $shipType = (string) $shipType;
00470 
00471                 // Is the class there?
00472                 if (!class_exists($shipType)) {
00473                         // Throw exception
00474                         throw new ClassNotFoundException($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
00475                 }
00476 
00477                 // Create dummy ship
00478                 eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");",
00479                         $shipType,
00480                         $shipType
00481                 ));
00482 
00483                 // Iterate shipyard list
00484                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
00485                         // Get current element
00486                         $shipyard = $idx->current();
00487 
00488                         // Is this a shipyard?
00489                         if (is_null($shipyard)) {
00490                                 // Opps! Empty list?
00491                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
00492                         } elseif (!is_object($shipyard)) {
00493                                 // Not an object! ;-(
00494                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
00495                         } elseif ($shipyard->isClass("Shipyard") === false) {
00496                                 // Class is not a shipyard
00497                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
00498                         }
00499 
00500                         // Add the new ship type to the shipyard
00501                         $shipyard->addNewConstructableShipType($shipType);
00502                 } // END - for
00503         }
00504 
00505         // Validate the requested ship type with the company if they can construct it
00506         public function validateWorksContractShipType (SignableContract $contractInstance) {
00507                 // First get the ship type
00508                 $shipInstance = $contractInstance->getShipInstance();
00509 
00510                 // Ist there a ship instance?
00511                 if (is_null($shipInstance)) {
00512                         // Opps! Empty entry?
00513                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
00514                 } elseif (!is_object($shipInstance)) {
00515                         // Not an object! ;-(
00516                         throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
00517                 }
00518 
00519                 // Get it's real class name
00520                 $shipType = $shipInstance->__toString();
00521 
00522                 // Now check if ship type is in any list and return the result
00523                 return ($this->isShipTypeConstructable($shipType));
00524         }
00525 
00526         // Is the ship type constructable?
00527         public function isShipTypeConstructable ($shipType) {
00528                 // The type must be a string!
00529                 $shipType = (string) $shipType;
00530 
00531                 // Debug message
00532                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> fragt alle Werften ab, ob diese Schiffe vom Typ <strong>%s</strong> bauen k&ouml;nnen.",
00533                         __CLASS__,
00534                         __LINE__,
00535                         $this->getCompanyName(),
00536                         $shipType
00537                 ));
00538 
00539                 // First everthing is failed...
00540                 $result = false;
00541 
00542                 // Iterate through all shipyards
00543                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
00544                         // Get current Shipyard instance
00545                         $shipyard = $idx->current();
00546 
00547                         // Is this a shipyard?
00548                         if (is_null($shipyard)) {
00549                                 // Opps! Empty list?
00550                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
00551                         } elseif (!is_object($shipyard)) {
00552                                 // Not an object! ;-(
00553                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
00554                         } elseif ($shipyard->isClass("Shipyard") === false) {
00555                                 // Class is not a shipyard
00556                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
00557                         }
00558 
00559                         // Validate if first found shipyard can construct the requested type
00560                         $result = $shipyard->isShipTypeConstructable($shipType);
00561 
00562                         // Does this shipyard construct the requested ship type?
00563                         if ($result) break; // Then abort the search!
00564                 } // END - for
00565 
00566                 // Debug message
00567                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat die Suche nach einer Werft beendet, die Schiffe vom Typ <strong>%s</strong> bauen kann.",
00568                         __CLASS__,
00569                         __LINE__,
00570                         $this->getCompanyName(),
00571                         $shipType
00572                 ));
00573 
00574                 // Return result
00575                 return $result;
00576         }
00577 
00578         // As a customer the shipping company can add new contracts
00579         public function addNewWorksContract (SignableContract $contractInstance) {
00580                 $this->contractList->append($contractInstance);
00581         }
00582 
00583         // As a customer the shippng company can withdraw from a contract
00584         public function withdrawFromContract (SignableContract $contractInstance) {
00585                 ApplicationEntryPoint::app_die("WITHDRAW:<pre>".print_r($contractInstance, true)."</pre>");
00586         }
00587 
00588         // Get latest added contract instance
00589         public final function getLastContractInstance () {
00590                 // Get iterator
00591                 $iter = $this->contractList->getIterator();
00592 
00593                 // Get latest entry (total - 1)
00594                 $iter->seek($iter->count() - 1);
00595 
00596                 // Return entry
00597                 return $iter->current();
00598         }
00599 
00600         // Sign a contract with an other party which must also implement Customer
00601         public function signContract (SignableContract $contractInstance, ContractPartner $partnerInstance) {
00602                 // Check wether the other party is our contract partner
00603                 if ($partnerInstance->isContractPartner($contractInstance) === false) {
00604                         // Invalid contract partner!
00605                         throw new InvalidContractPartnerException($partnerInstance, self::EXCEPTION_CONTRACT_PARTNER_INVALID);
00606                 } // END - if
00607 
00608                 // Determine if company "signs" own contract (must be done) or with an other party
00609                 if ($this->equals($partnerInstance)) {
00610                         // With itself
00611                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erteilt an sich selbst einen Bauauftrag f&uuml;r das <strong>%s</strong> &quot;<strong>%s</strong>&quot;.",
00612                                 __CLASS__,
00613                                 __LINE__,
00614                                 $this->getCompanyName(),
00615                                 $contractInstance->getShipInstance()->getObjectDescription(),
00616                                 $contractInstance->getShipInstance()->getShipName()
00617                         ));
00618                 } else {
00619                         // Other external company
00620                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> unterzeichnet einen Bauauftrag f&uuml;r das <strong>%s</strong> &quot;<strong>%s</strong>&quot; mit der <strong>%s</strong>.",
00621                                 __CLASS__,
00622                                 __LINE__,
00623                                 $this->getCompanyName(),
00624                                 $contractInstance->getShipInstance()->getObjectDescription(),
00625                                 $contractInstance->getShipInstance()->getShipName(),
00626                                 $partnerInstance->getCompanyName()
00627                         ));
00628                 }
00629 
00630                 // Sign the contract
00631                 $contractInstance->signContract($this, $partnerInstance);
00632 
00636         }
00637 
00638         // Is this the right contract partner?
00639         public function isContractPartner (SignableContract $contractInstance) {
00640                 // Get contract partner instance and compare it with $this contract partner
00641                 return ($this->equals($contractInstance->getContractPartner()));
00642         }
00643 
00644         // Setter for merchant instance
00645         public final function setMerchantInstance (Merchant $merchantInstance) {
00646                 // Get contract
00647                 $contractInstance = $this->getLastContractInstance();
00648 
00649                 if (is_null($contractInstance)) {
00650                         // Opps! Empty contract instance?
00651                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
00652                 } elseif (!is_object($contractInstance)) {
00653                         // Not an object! ;-(
00654                         throw new NoObjectException($contractInstance, self::EXCEPTION_IS_NO_OBJECT);
00655                 } elseif ($contractInstance->isClass("WorksContract") === false) {
00656                         // Is not a merchant
00657                         throw new ClassMismatchException(array($contractInstance->__toString(), "WorksContract"), self::EXCEPTION_CLASSES_NOT_MATCHING);
00658                 }
00659 
00660                 // Set the merchant in the contract (for getting prices)
00661                 $contractInstance->setMerchantInstance($merchantInstance);
00662         }
00663 }
00664 
00665 // [EOF]
00666 ?>

Generated on Mon Dec 8 01:06:44 2008 for Ship-Simulator by  doxygen 1.5.6