void FontDescriptorWriter::WriteFontDescriptor(	ObjectIDType inFontDescriptorObjectID,
												const string& inFontPostscriptName,
												FreeTypeFaceWrapper* inFontInfo,
												const UIntAndGlyphEncodingInfoVector& inEncodedGlyphs,
												ObjectsContext* inObjectsContext,
												IFontDescriptorHelper* inDescriptorHelper)
{
	DictionaryContext* fontDescriptorDictionary;

	inObjectsContext->StartNewIndirectObject(inFontDescriptorObjectID);
	fontDescriptorDictionary = inObjectsContext->StartDictionary();
	
	// FontName
	fontDescriptorDictionary->WriteKey(scFontName);
	fontDescriptorDictionary->WriteNameValue(inFontPostscriptName);

	// FontFamily
	fontDescriptorDictionary->WriteKey(scFontFamily);
	fontDescriptorDictionary->WriteLiteralStringValue((*inFontInfo)->family_name);

	// FontStretch
	fontDescriptorDictionary->WriteKey(scFontStretch);
	fontDescriptorDictionary->WriteNameValue(scFontStretchLabels[inFontInfo->GetFontStretch()]);

	// FontWeight
	fontDescriptorDictionary->WriteKey(scFontWeight);
	fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetFontWeight());

	// FontBBox
	fontDescriptorDictionary->WriteKey(scFontBBox);
	fontDescriptorDictionary->WriteRectangleValue(
											PDFRectangle(
												inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.xMin),
												inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.yMin),
												inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.xMax),
												inFontInfo->GetInPDFMeasurements((*inFontInfo)->bbox.yMax)));

	// ItalicAngle
	fontDescriptorDictionary->WriteKey(scItalicAngle);
	fontDescriptorDictionary->WriteDoubleValue(inFontInfo->GetItalicAngle());

	// Ascent
	fontDescriptorDictionary->WriteKey(scAscent);
	fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetInPDFMeasurements((*inFontInfo)->ascender));

	// Descent
	fontDescriptorDictionary->WriteKey(scDescent);
	fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetInPDFMeasurements((*inFontInfo)->descender));

	// CapHeight
	BoolAndFTShort result =  inFontInfo->GetCapHeight();
	if(result.first)
	{
		fontDescriptorDictionary->WriteKey(scCapHeight);
		fontDescriptorDictionary->WriteIntegerValue(result.second);
	}

	// XHeight
	result = inFontInfo->GetxHeight();
	if(result.first)
	{
		fontDescriptorDictionary->WriteKey(scXHeight);
		fontDescriptorDictionary->WriteIntegerValue(result.second);
	}


	// StemV
	fontDescriptorDictionary->WriteKey(scStemV);
	fontDescriptorDictionary->WriteIntegerValue(inFontInfo->GetStemV());

	// ChartSet writing (variants according to ANSI/CID)
	inDescriptorHelper->WriteCharSet(fontDescriptorDictionary,inObjectsContext,inFontInfo,inEncodedGlyphs);

	// Flags
	fontDescriptorDictionary->WriteKey(scFlags);
	fontDescriptorDictionary->WriteIntegerValue(CalculateFlags(inFontInfo,inEncodedGlyphs));

	// font embedding [may not happen due to font embedding restrictions. helper is supposed to avoid reference as well]
	inDescriptorHelper->WriteFontFileReference(fontDescriptorDictionary,inObjectsContext);

	inObjectsContext->EndDictionary(fontDescriptorDictionary);
	inObjectsContext->EndIndirectObject();
}
EStatusCodeAndObjectIDType PDFCommentWriter::WriteCommentsTree(PDFComment* inComment)
{
	EStatusCodeAndObjectIDType result;
	ObjectIDType repliedTo = 0;

	// if already written, return
	PDFCommentToObjectIDTypeMap::iterator it = mCommentsForNextPage.find(inComment);
	if(it != mCommentsForNextPage.end())
	{
		result.first = eSuccess;
		result.second = it->second;
		return result;
	}

	// if has a referred comment, write it first
	if(inComment->ReplyTo != NULL)
	{
		EStatusCodeAndObjectIDType repliedtoResult = WriteCommentsTree(inComment->ReplyTo);

		if(repliedtoResult.first != eSuccess)
		{
			result.first = eFailure;
			result.second = 0;
			return result;
		}
		else
			repliedTo = repliedtoResult.second;
	}

	do
	{
		ObjectsContext& objectsContext = mPDFWriter->GetObjectsContext();

		// Start new InDirect object for annotation dictionary
		result.second = objectsContext.StartNewIndirectObject();
		
		DictionaryContext* dictionaryContext = objectsContext.StartDictionary();


		// Type
		dictionaryContext->WriteKey("Type");
		dictionaryContext->WriteNameValue("Annot");

		// SubType
		dictionaryContext->WriteKey("Subtype");
		dictionaryContext->WriteNameValue("Text");

		// Rect
		dictionaryContext->WriteKey("Rect");
		dictionaryContext->WriteRectangleValue(
			PDFRectangle(inComment->FrameBoundings[0],
						 inComment->FrameBoundings[1],
						 inComment->FrameBoundings[2],
						 inComment->FrameBoundings[3]));

		// Contents 
		dictionaryContext->WriteKey("Contents");
		dictionaryContext->WriteLiteralStringValue(PDFTextString(inComment->Text).ToString());

		// C (color)
		dictionaryContext->WriteKey("C");
		objectsContext.StartArray();
		if(inComment->Color.UseCMYK)
		{
			objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[0]/255);
			objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[1]/255);
			objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[2]/255);
			objectsContext.WriteDouble((double)inComment->Color.CMYKComponents[3]/255);
		}
		else
		{
			objectsContext.WriteDouble((double)inComment->Color.RGBComponents[0]/255);
			objectsContext.WriteDouble((double)inComment->Color.RGBComponents[1]/255);
			objectsContext.WriteDouble((double)inComment->Color.RGBComponents[2]/255);
		}
		objectsContext.EndArray(eTokenSeparatorEndLine);

		// T
		dictionaryContext->WriteKey("T");
		dictionaryContext->WriteLiteralStringValue(PDFTextString(inComment->CommentatorName).ToString());
		
		// M
		dictionaryContext->WriteKey("M");
		dictionaryContext->WriteLiteralStringValue(inComment->Time.ToString());

		if(inComment->ReplyTo != NULL)
		{
			// IRT
			dictionaryContext->WriteKey("IRT");
			dictionaryContext->WriteObjectReferenceValue(repliedTo);

			// RT (we're doing always "reply" at this point, being a reply to comment
			dictionaryContext->WriteKey("RT");
			dictionaryContext->WriteNameValue("R");
		}

		// Open (we'll have them all closed to begin with)
		dictionaryContext->WriteKey("Open");
		dictionaryContext->WriteBooleanValue(false);

		// Name
		dictionaryContext->WriteKey("Name");
		dictionaryContext->WriteNameValue("Comment");

		if(objectsContext.EndDictionary(dictionaryContext) != eSuccess)
		{
			result.first = eFailure;
			TRACE_LOG("PDFCommentWriter::WriteCommentsTree, Exception in ending comment dictionary");
			break;
		}
		objectsContext.EndIndirectObject();
	
		mCommentsForNextPage.insert(PDFCommentToObjectIDTypeMap::value_type(inComment,result.second));

		result.first = eSuccess;
	}while(false);
	
	return result;
}