SCNXArchive& SCNXArchiveFactory::getSCNXArchive(const URL &url) throw (InvalidArgumentException) {
            if (!(url.isValid())) {
                OPENDAVINCI_CORE_THROW_EXCEPTION(InvalidArgumentException, "URL is invalid.");
            }

            SCNXArchive *scnxArchive = NULL;

            // Try to find an existing SCNXArchive in the map using the URL as key.
            map<string, SCNXArchive*, core::strings::StringComparator>::iterator it = m_mapOfSCNXArchives.find(url.toString());
            if (it != m_mapOfSCNXArchives.end()) {
            	clog << "Found already constructed data structure." << endl;
                scnxArchive = it->second;
            }

            if (scnxArchive == NULL) {
                clog << "Creating new SCNXArchive from " << url.toString() << endl;

                string fileName = url.getResource();
                fstream fin(fileName.c_str(), ios::binary | ios::in);
                core::SharedPointer<core::wrapper::DecompressedData> data = core::wrapper::CompressionFactory::getContents(fin);
                fin.close();

                if (data.isValid()) {
                    Scenario scenario;
                    SharedPointer<istream> stream = data->getInputStreamFor("scenario.scn");
                    if (stream.isValid()) {
                        stringstream s;
                        char c;
                        while (stream->good()) {
                            stream->get(c);
                            s << c;
                        }

                        // Trying to parse the input.
                        scenario = ScenarioFactory::getInstance().getScenario(s.str());
                    } else {
                        OPENDAVINCI_CORE_THROW_EXCEPTION(InvalidArgumentException, "Archive from the given URL does not contain a valid SCN file.");
                    }

                    // Create SCNXArchive.
                    scnxArchive = new SCNXArchive(scenario, data);

                    // Store SCNXArchive for further usage.
                    // Somehow, there seems to be a bug because the data structure got corrupt...
//                    m_mapOfSCNXArchives[url.toString()] = scnxArchive;
                }
                else {
                    OPENDAVINCI_CORE_THROW_EXCEPTION(InvalidArgumentException, "URL could not be used to read input data.");
                }
            }

            return *scnxArchive;
        }
            OBJXArchive* OBJXArchiveFactory::getOBJXArchive(istream &in) throw (InvalidArgumentException) {
                if (!(in.good())) {
                    // Try to rewind the stream.
                    clog << "Trying to rewind the stream." << endl;
                    in.clear();
                    in.seekg(ios::beg);

                    if (!(in.good())) {
                        OPENDAVINCI_CORE_THROW_EXCEPTION(InvalidArgumentException, "Given inputstream is invalid.");
                    }
                }

                OBJXArchive *objxArchive = NULL;

                // Use CompressionFactory to read the contents of the OBJXArchive.
                SharedPointer<core::wrapper::DecompressedData> data = core::wrapper::CompressionFactory::getContents(in);

                if (data.isValid()) {
                    // Create OBJXArchive.
                    objxArchive = new OBJXArchive();

                    vector<string> listOfEntries = data->getListOfEntries();
                    vector<string>::iterator it = listOfEntries.begin();

                    while (it != listOfEntries.end()) {
                        string entry = (*it++);

                        if (entry.find(".obj") != string::npos) {
                            // Set object file.
                            SharedPointer<istream> stream = data->getInputStreamFor(entry);
                            if (stream.isValid()) {
                                char c;
                                stringstream s;
                                while (stream->good()) {
                                    stream->get(c);
                                    s << c;
                                }
                                objxArchive->setContentsOfObjFile(s.str());
                            }
                        } else if (entry.find(".mtl") != string::npos) {
                            // Set material file.
                            SharedPointer<istream> stream = data->getInputStreamFor(entry);
                            if (stream.isValid()) {
                                char c;
                                stringstream s;
                                while (stream->good()) {
                                    stream->get(c);
                                    s << c;
                                }
                                objxArchive->setContentsOfMtlFile(s.str());
                            }
                        } else {
                            // Try to load an image.
                            SharedPointer<istream> stream = data->getInputStreamFor(entry);

                            if (stream.isValid()) {
                                core::wrapper::Image *image = core::wrapper::ImageFactory::getInstance().getImage(*stream);

                                if (image != NULL) {
                                    // TODO: Check where origin lies.
                                    image->rotate(static_cast<float>(cartesian::Constants::PI));

                                    // Remove any directory prefixes from the entry.
                                    string name = entry;
                                    if (name.rfind('/') != string::npos) {
                                        name = name.substr(name.rfind('/') + 1);
                                    }

                                    objxArchive->addImage(name, image);
                                }
                            }
                        }

                    }
                }

                return objxArchive;
            }