public function getAttachment(IRI $coid, $filename) {
		$object = $this->getObject($coid);

		if (!$object)
			// Cannot get attachment for non-existing object
			return null;

		$ts = microtime(true);

		$cacheId = $object->getId().'#'.$filename;
		$fileData =  $this->getFromCache($cacheId);

		// Parse cached data into revision and content
		if (isset($fileData)) {
			$this->logInfoWithTime('Fetched attachment <'.$filename.'> for <'.$object->getId().'> from object cache.', $ts);
			list($fileRevision, $fileContent) = explode('#', $fileData, 2);
		}

		if (!isset($fileData)
				|| $fileRevision!=$object->getProperty(self::REVISION_PROPERTY)->getValue()) {

			// Does not exist in cache or is outdated, fetch from CloudObjects
			try {
				$response = $this->client->get((isset($this->prefix) ? $this->prefix : '').$coid->getHost().$coid->getPath()
					.'/'.basename($filename));

				$fileContent = $response->getBody()->getContents();
				$fileData = $object->getProperty(self::REVISION_PROPERTY)->getValue().'#'.$fileContent;
				$this->putIntoCache($cacheId, $fileData, 0);

				$this->logInfoWithTime('Fetched attachment <'.$filename.'> for <'.$object->getId().'> from Core API ['.$response->getStatusCode().'].', $ts);
			} catch (\Exception $e) {
				$this->logInfoWithTime('Attachment <'.$filename.'> for <'.$object->getId().'> not found in Core API ['.$e->getResponse()->getStatusCode().'].', $ts);
				// ignore exception - treat as non-existing file
			}

		}

		return $fileContent;
	}