Handle<Value> DocumentCopyingContextDriver::CopyNewObjectsForDirectObject(const Arguments& args)
{
    HandleScope scope;
    
    DocumentCopyingContextDriver* copyingContextDriver = ObjectWrap::Unwrap<DocumentCopyingContextDriver>(args.This());
    
    if(!copyingContextDriver->CopyingContext)
    {
		ThrowException(Exception::TypeError(String::New("copying context object not initialized, create using pdfWriter.createPDFCopyingContext or PDFWriter.createPDFCopyingContextForModifiedFile")));
        return scope.Close(Undefined());
    }
    
    if(!args.Length() == 1 ||
       !args[0]->IsArray())
    {
		ThrowException(Exception::TypeError(String::New("Wrong arguments. provide 1 arugment, which is an array of object IDs")));
        return scope.Close(Undefined());
    }
    
    ObjectIDTypeList objectIDs;
    Handle<Object> objectIDsArray = args[0]->ToObject();

    unsigned int length = objectIDsArray->Get(v8::String::New("length"))->ToObject()->Uint32Value();
    
    for(unsigned int i=0;i <length;++i)
        objectIDs.push_back(objectIDsArray->Get(i)->ToNumber()->Uint32Value());
    
    EStatusCode status = copyingContextDriver->CopyingContext->CopyNewObjectsForDirectObject(objectIDs);
    if(status != eSuccess)
		ThrowException(Exception::Error(String::New("Unable to copy elements")));
    return scope.Close(Undefined());
    
}
EStatusCode UsedFontsRepository::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID)
{
	EStatusCode status = PDFHummus::eSuccess;
	ObjectIDTypeList usedFontsObjects;

	inStateWriter->StartNewIndirectObject(inObjectID);
	DictionaryContext* usedFontsRepositoryObject = inStateWriter->StartDictionary();

	usedFontsRepositoryObject->WriteKey("Type");
	usedFontsRepositoryObject->WriteNameValue("UsedFontsRepository");

	usedFontsRepositoryObject->WriteKey("mUsedFonts");
	inStateWriter->StartArray();


	StringAndLongToPDFUsedFontMap::iterator it = mUsedFonts.begin();

	for(; it != mUsedFonts.end();++it)
	{
		PDFTextString aTextString(it->first.first);
		inStateWriter->WriteLiteralString(aTextString.ToString());
        
        inStateWriter->WriteInteger(it->first.second);
		
		ObjectIDType usedFontID = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID();
		inStateWriter->WriteNewIndirectObjectReference(usedFontID);
		usedFontsObjects.push_back(usedFontID);
	}

	inStateWriter->EndArray(eTokenSeparatorEndLine);

	usedFontsRepositoryObject->WriteKey("mOptionaMetricsFiles");
	inStateWriter->StartArray();

	StringToStringMap::iterator itOptionals = mOptionaMetricsFiles.begin();
	for(; itOptionals != mOptionaMetricsFiles.end();++itOptionals)
	{
		PDFTextString aTextString(itOptionals->first);
		inStateWriter->WriteLiteralString(aTextString.ToString());

		aTextString = itOptionals->second;
		inStateWriter->WriteLiteralString(aTextString.ToString());
	}

	inStateWriter->EndArray(eTokenSeparatorEndLine);

	inStateWriter->EndDictionary(usedFontsRepositoryObject);
	inStateWriter->EndIndirectObject();

	if(usedFontsObjects.size() > 0)
	{
		it = mUsedFonts.begin();
		ObjectIDTypeList::iterator itIDs = usedFontsObjects.begin();

		for(; it != mUsedFonts.end() && PDFHummus::eSuccess == status;++it,++itIDs)
			status = it->second->WriteState(inStateWriter,*itIDs);
	}

	return status;
}
METHOD_RETURN_TYPE DocumentCopyingContextDriver::CopyNewObjectsForDirectObject(const ARGS_TYPE& args)
{
	CREATE_ISOLATE_CONTEXT;
	CREATE_ESCAPABLE_SCOPE;

    DocumentCopyingContextDriver* copyingContextDriver = ObjectWrap::Unwrap<DocumentCopyingContextDriver>(args.This());
    
    if(!copyingContextDriver->CopyingContext)
    {
		THROW_EXCEPTION("copying context object not initialized, create using pdfWriter.createPDFCopyingContext or PDFWriter.createPDFCopyingContextForModifiedFile");
        SET_FUNCTION_RETURN_VALUE(UNDEFINED);
    }
    
    if(args.Length() != 1 ||
       !args[0]->IsArray())
    {
		THROW_EXCEPTION("Wrong arguments. provide 1 arugment, which is an array of object IDs");
        SET_FUNCTION_RETURN_VALUE(UNDEFINED);
    }
    
    ObjectIDTypeList objectIDs;
    Handle<Object> objectIDsArray = args[0]->ToObject();

    unsigned int length = objectIDsArray->Get(v8::NEW_STRING("length"))->ToObject()->Uint32Value();
    
    for(unsigned int i=0;i <length;++i)
        objectIDs.push_back(objectIDsArray->Get(i)->ToNumber()->Uint32Value());
    
    EStatusCode status = copyingContextDriver->CopyingContext->CopyNewObjectsForDirectObject(objectIDs);
    if(status != eSuccess)
		THROW_EXCEPTION("Unable to copy elements");
    SET_FUNCTION_RETURN_VALUE(UNDEFINED);
    
}
EStatusCode IndirectObjectsReferenceRegistry::WriteState(ObjectsContext* inStateWriter,ObjectIDType inObjectID)
{
	ObjectIDTypeList objects;

	inStateWriter->StartNewIndirectObject(inObjectID);
	
	DictionaryContext* myDictionary = inStateWriter->StartDictionary();
	
	myDictionary->WriteKey("Type");
	myDictionary->WriteNameValue("IndirectObjectsReferenceRegistry");

	myDictionary->WriteKey("mObjectsWritesRegistry");
	
	ObjectWriteInformationVector::iterator it = mObjectsWritesRegistry.begin();

	inStateWriter->StartArray();
	for(; it != mObjectsWritesRegistry.end(); ++it)
	{
		ObjectIDType objectWriteEntry = inStateWriter->GetInDirectObjectsRegistry().AllocateNewObjectID();
		inStateWriter->WriteIndirectObjectReference(objectWriteEntry);
		objects.push_back(objectWriteEntry);
	}
	inStateWriter->EndArray(eTokenSeparatorEndLine);

	inStateWriter->EndDictionary(myDictionary);
	inStateWriter->EndIndirectObject();

	ObjectIDTypeList::iterator itIDs = objects.begin();

	it = mObjectsWritesRegistry.begin();

	for(; it != mObjectsWritesRegistry.end(); ++it,++itIDs)
	{
		inStateWriter->StartNewIndirectObject(*itIDs);

		DictionaryContext* registryDictionary = inStateWriter->StartDictionary();
		
		registryDictionary->WriteKey("Type");
		registryDictionary->WriteNameValue("ObjectWriteInformation");

		registryDictionary->WriteKey("mObjectWritten");
		registryDictionary->WriteBooleanValue(it->mObjectWritten);

		if(it->mObjectWritten)
		{
			registryDictionary->WriteKey("mWritePosition");
			registryDictionary->WriteIntegerValue(it->mWritePosition);
		}

		registryDictionary->WriteKey("mObjectReferenceType");
		registryDictionary->WriteIntegerValue(it->mObjectReferenceType);

		inStateWriter->EndDictionary(registryDictionary);
		inStateWriter->EndIndirectObject();
	}

	return PDFHummus::eSuccess;
}
EStatusCode DCTDecodeFilterTest::ModifyImageObject(PDFWriter* inWriter,ObjectIDType inImageObject)
{
    EStatusCode status = eSuccess;
    PDFDocumentCopyingContext* modifiedFileContext = inWriter->CreatePDFCopyingContextForModifiedFile();
    
    do
    {
        // get image source dictionary
        PDFObjectCastPtr<PDFStreamInput> imageStream(inWriter->GetModifiedFileParser().ParseNewObject(inImageObject));
        
        RefCountPtr<PDFDictionary> imageDictionary(imageStream->QueryStreamDictionary());
        
        // strt object for modified image
        inWriter->GetObjectsContext().StartModifiedIndirectObject(inImageObject);
        
        DictionaryContext* newImageDictionary = inWriter->GetObjectsContext().StartDictionary();
        
        MapIterator<PDFNameToPDFObjectMap> it = imageDictionary->GetIterator();
        
        // copy all but "Filter" and "Length"
        ObjectIDTypeList indirectObjects;
        
        while (it.MoveNext())
        {
            if(it.GetKey()->GetValue() == "Filter" || it.GetKey()->GetValue() == "Length")
                continue;
            
            newImageDictionary->WriteKey(it.GetKey()->GetValue());
            EStatusCodeAndObjectIDTypeList result = modifiedFileContext->CopyDirectObjectWithDeepCopy(it.GetValue());
            if(result.first != eSuccess)
            {
                status = result.first;
                break;
            }
            indirectObjects.insert(indirectObjects.end(),result.second.begin(),result.second.end());
        }
        if(status != eSuccess)
            break;
        
        // start image stream for this dictionary (make sure it's unfiltered)
        PDFStream* newImageStream = inWriter->GetObjectsContext().StartUnfilteredPDFStream(newImageDictionary);
        
        // copy source stream through read filter
        IByteReader* sourceImage = modifiedFileContext->GetSourceDocumentParser()->StartReadingFromStream(imageStream.GetPtr());
        if(!sourceImage)
        {
            cout<<"failed to read DCT stream\n";
            status = eFailure;
            break;
        }
        
        OutputStreamTraits traits(newImageStream->GetWriteStream());
        status = traits.CopyToOutputStream(sourceImage);
        
        // finalize stream
        inWriter->GetObjectsContext().EndPDFStream(newImageStream);
        delete newImageStream;
 
        // late check for status so stream is deleted
        if(status != eSuccess)
            break;
        
        // copy remaining indirect objects from image stream dictionary
        status = modifiedFileContext->CopyNewObjectsForDirectObject(indirectObjects);
        
    }
    while (false);
    
    delete modifiedFileContext;
    return status;
    
}